- Home /
Efficient sprite sheet animation with Editor preview
Hi,
I am looking for an efficient solution to render a somewhat large number of animated sprites in an efficient way. The context is a 2D game with pixel art, where sprites animations are baked into a sprite sheet and simply consist in sliding one or both of the UV coordinates. This also requires being able to use a custom shader.
Here's what I tried:
Animator
The Animator
way is not only complete overkill, it is also a time sink to create animation assets and assign all the components for each animated sprite. I believe the Animator
was not designed for that, but for more complex scenarios with numerous states and transitions, like character animation where I already use it and it is a perfect fit.
SpriteRenderer
This sounds like the natural fit, and indeed I could find several examples of MonoBehaviour
components written to animate the SpriteRenderer.sprite
property. This is so far the best approach I could find, although I am not entirely convinced by it as creating one Sprite asset per frame, although made relatively simple with the slicing tool of the sprite editor, is still a net overhead knowing the UV coordinates can be predicted from the frame index and everything else is static.
Dynamic Mesh
This was a promising alternative, which consists in generating at runtime on enabled a dynamic quad mesh, and assigning the texture sheet, then animating the _MainTex_ST
with a MaterialPropertyBlock
. This works well at runtime, but unfortunately the editing experience is poor, as the Editor won't render the mesh unless it is generated, which requires [ExecuteInEditMode]
or a more complex solution based on Editor.OnSceneGUI()
. The former is ugly, has some side effects (executes also other logic on the component aside from animation), and will leave some Prefab override and will get serialized in the scene for reasons I cannot understand.
SpriteRenderer with UV offset/scale
This would be a good alternative, creating a Sprite
object dynamically on the fly and animating again _MainTex_ST
. Unfortunately it seems that _MainTex_ST
is ignored when the shader is used with a SpriteRenderer
, likely because it is overridden by the Sprite
's own UV data. Maybe there is a way using a different property instead of _MainTex_ST
? In any case this still involves a Sprite
object which is a net overhead.
Any idea on a performant approach which would reduce the editing pain of creating extra assets per sprite sheet, while allowing mesh preview in the Editor (ideally animated when selected, but static preview is fine too)?
Thanks!