Animating voxels as if they were 2d sprites in unity3d. Is there a better way than this?

1.5k Views Asked by At

I'm making voxel models, which I love as I love pixelart. The models I want to use in unity are very small humanoids and purely for function.

As I look around for ways to animate these voxel models, all i really see is ways to add bones/rigs, creating a smooth animation which imo belies the voxel style.

I wanted to make these voxels animate in the same way that a 2D sprite is animated. For example my best and so far only technique for jumping animation is to destroy the standing voxel object and instantly instantiate the jumping voxel model object when I press jump. No transition involved, just the old school sprite style animation; like Mario.

My code for this was going to be (obviously not literally, but you get the idea):

if (player presses jump){
    destroy.this.gameobject
    instantiate prefab (jumpmanvoxelmodel)
}

Is this really the best method for doing this on unity? I'm making every frame of the animation in qubicle (at present), using the standing voxel as the child object and then destroying and instantiating the different prefabs (which serve as frames of animation) relative to user input.

Is anyone animating voxels without rigs? Am I barking up the wrong tree?

Thanks

This is what I mean if it's unclear: https://www.youtube.com/watch?v=u2e8lfViIxg

1

There are 1 best solutions below

1
On

I'd suggest you treat the voxel models just the same way as if they were 2D sprites. Have a mesh of each and every animation frame, and just switch the meshes. That way you don't produce garbage objects that have to be collected by the Garbage Collector.

Here is a basic example that just runs from first to last frame over and over.

class MeshAnimation : MonoBehaviour
{
    public Mesh[] frames = new Mesh[0];
    public float animationSpeed = .1f;

    private float animationStartTime;
    private int currentFrame;

    void Start()
    {
        currentFrame = 0;
        animationStartTime = Time.time;
        UpdateMesh();
    }

    void Update()
    {
        currentFrame = Mathf.FloorToInt((Time.time - animationStartTime) / animationSpeed);
        currentFrame = currentFrame % frames.Length;
        UpdateMesh();
    }

    void UpdateMesh()
    {
        GetComponent<MeshFilter>().mesh = frames[currentFrame];
    }
}