I am trying to implement a simple abstraction over SpriteAtlas
where I can simply request texture coordinates for a certain BlockType
(each BlockType
has associated texture with it that is packed inside a SpriteAtlas
. Imagine dirt, stone, water etc.). To achieve just that, I've created a simple ScriptableObject
class that is given a reference to the SpriteAtlas
and in its OnEnable
method it tries to extract all of the texture coordinates from the sprite atlas:
[SerializeField] private SpriteAtlas spriteAtlas;
private readonly Dictionary<BlockType, Vector2[]> _blockTypeToTextureCoordinates = new Dictionary<BlockType, Vector2[]>();
private Sprite[] _sprites;
private void OnEnable()
{
LoadAllSpritesFromSpriteAtlas(); // This method works perfectly fine.
ExtractTextureCoordinatesFromEachSprite(); // This method has a problem in it.
}
private void LoadAllSpritesFromSpriteAtlas()
{
_sprites = new Sprite[spriteAtlas.spriteCount];
spriteAtlas.GetSprites(_sprites);
}
private void ExtractTextureCoordinatesFromEachSprite()
{
foreach (var sprite in _sprites)
{
if (!Enum.TryParse(sprite.texture.name, out BlockType blockType))
{
Debug.LogError($"'{sprite.texture.name}' could not be converted to a block type.");
continue;
}
// I've been in debugger and sprite is not yet packed.
_blockTypeToTextureCoordinates[blockType] = sprite.uv;
}
}
The problem lies in the last method ExtractTextureCoordinatesFromEachSprite
, where when I am trying to get sprite texture coordinates (uv), it always returns {(0, 0), (0, 1), (1, 0), (1, 1)}
, which is a full sprite atlas texture, instead of only a small portion of it (some small texture coordinate numbers between 0 and 1). I used debugger and it said that sprite.packed
variable is set to false
(meaning the sprites are not yet packed at this point in time). However, if I would do exactly the same code in MonoBehaviour
class' Awake
method, everything would work fine and sprites would be packed when accessed and appropriate UV coordinates would get returned.
However, I'd really love if I could do it inside a ScriptableObject
and it really makes no sense that sprites are not initialized at that point since this information could easily be created even before the game is run. Can anyone help me understand why the sprites are not packed when accessed in OnEnable
method of ScriptableObject
and is there a way to make it work somehow?