//##############################################################################################
    // Get the needed components, and set up the timer. Then, populate the materials from either
    // ourselves or a RotatableComponent. Then, if needed, roll a random start index.
    // Finally, cache the length, set the first-indexed material, and clear the 'finished' flag
    //##############################################################################################
    void Start()
    {
        meshRenderer = GetComponent <MeshRenderer>();
        rotatable    = GetComponent <RotatableComponent>();

        frameTime = 1.0f / frameRate;

        frameTimer = new Timer(frameTime);
        frameTimer.Start();

        if (ShouldUseRotatable())
        {
            usingMaterials = rotatable.GetAnimation();
        }
        else
        {
            usingMaterials = materials;
        }

        if (randomStartIndex)
        {
            frameIndex = Random.Range(0, usingMaterials.Length);
        }
        else
        {
            frameIndex = 0;
        }

        previousMaterialCount = usingMaterials.Length;
        meshRenderer.material = usingMaterials[frameIndex];
        finished = false;
    }
    //##############################################################################################
    // Update the materials list if needed, then increment the animation if the frame timer is done
    //##############################################################################################
    void Update()
    {
        if (ShouldUseRotatable())
        {
            usingMaterials = rotatable.GetAnimation();
        }
        else
        {
            usingMaterials = materials;
        }

        // If the materials changed, reset the animation
        if (usingMaterials.Length != previousMaterialCount)
        {
            frameTimer.Start();

            frameIndex            = 0;
            previousMaterialCount = usingMaterials.Length;

            meshRenderer.material = usingMaterials[frameIndex];

            return;
        }

        if (frameTimer.Finished())
        {
            frameTimer.Start();

            if (looping)
            {
                frameIndex = (frameIndex + 1) % usingMaterials.Length;
            }
            else
            {
                frameIndex++;

                if (frameIndex == usingMaterials.Length)
                {
                    finished = true;

                    if (destroyOnFinish)
                    {
                        Destroy(gameObject);
                    }
                }

                frameIndex = Mathf.Min(frameIndex, usingMaterials.Length - 1);
            }

            meshRenderer.material = usingMaterials[frameIndex];
        }
    }