1
\$\begingroup\$

I bought an asset the other day containing an Atlas of character parts (head, hairs, clothes, body-parts). It's great and allows me to tint each piece any color I want. However, The artist decided to devide up the character like this:

enter image description here

Each child is a fully setup character, facing a certain direction, with an Animator attached to it, inside each Animator Controller you find this:

enter image description here

Some sample animations, pretty self-explanatory. However, I have never worked with sprites like this where its several parts, the entire character is maybe 30-40 parts (allowing for some fun animations). I'm used to making Blend Trees (on a single GameObject) and have one animation for each direction. The best solution for controlling these animations I could think of was something like this:

private void AnimControl() //call in update
    {
        if(direction != directionLastFrame) //do not run method if we are moving same direction
        {
            //standing still
            if (direction.x == 0 && direction.y == 0)
            {
                directionLastFrame = direction;
            }
            ////left
            else if (direction.x < 0.5f && direction.y == 0)
            {
                currentCharacterDirection.SetActive(false); //set current gameObject (which is a character facing a certain direction) inactive
                currentCharacterDirection = character.leftDirection; //change to correct direction
                currentCharacterDirection.SetActive(true); //set gameobject active again
                anim = currentCharacterDirection.GetComponent<Animator>(); //set the animation controller to the new gameObject
                directionLastFrame = direction; //set the new direction to check for
            }
            ////right
            else if (direction.x >= 0.5f && direction.y == 0)
            {
                currentCharacterDirection.SetActive(false);
                currentCharacterDirection = character.rightDirection;
                currentCharacterDirection.SetActive(true);
                anim = currentCharacterDirection.GetComponent<Animator>();
                directionLastFrame = direction;
            }
            ////down
            else if (direction.y < 0.5f && direction.x == 0)
            {
                currentCharacterDirection.SetActive(false);
                currentCharacterDirection = character.downDirection;
                currentCharacterDirection.SetActive(true);
                anim = currentCharacterDirection.GetComponent<Animator>();
                directionLastFrame = direction;
            }
            ////up
            else if (direction.y >= 0.5f && direction.x == 0)
            {
                currentCharacterDirection.SetActive(false);
                currentCharacterDirection = character.upDirection;
                currentCharacterDirection.SetActive(true);
                anim = currentCharacterDirection.GetComponent<Animator>();
                directionLastFrame = direction;
            }
        }

        anim.SetBool("Moving", playerMoving);
    }

I mean it works, but feels wrong? Anyone that can think of a better Idea here, worried this might be too slow. setting an object to active/inactive too often.

\$\endgroup\$
2
\$\begingroup\$

The only things I see you could do to optimize your solution are:

  • Avoid calling GetComponent() on each frame, by adding to the script that have attached your child characters an Animator property, so they have their own animator property
  • Your direction assignation could be assigned just once, since in all of you if-else cases, direction gets the same value.
  • Similarly to the direction assignation, in all your if-else cases, you are first deactivating your character, then activating the new character, so you can avoid redundancy by doing those procedures at the start and end, respectively.

Since I don't know the common script both your parent and child characters have, I'll give my example with a custom script (you'd just need to add that on the scripts you know they have):

public class AnimatorCharacter : MonoBehaviour
{
    private Animator _animator;

    public Animator GetAnimator() { return _animator; }

    void Awake()
    {
        _animator = GetComponent<Animator>();
    }
}

So, in your implementation you'd do something like this:

private void AnimControl() //call in update
{
    if(direction != directionLastFrame) //do not run method if we are moving same direction
    {
        currentCharacterDirection.SetActive(false); //set current gameObject (which is a character facing a certain direction) inactive

        //standing still
        if (direction.x == 0 && direction.y == 0)
        {
            //...
        }
        ////left
        else if (direction.x < 0.5f && direction.y == 0)
        {
            currentCharacterDirection = character.leftDirection; //change to correct direction 
        }
        ////right
        else if (direction.x >= 0.5f && direction.y == 0)
        {
            currentCharacterDirection = character.rightDirection;
        }
        ////down
        else if (direction.y < 0.5f && direction.x == 0)
        {
            currentCharacterDirection = character.downDirection;
        }
        ////up
        else if (direction.y >= 0.5f && direction.x == 0)
        {
            currentCharacterDirection = character.upDirection;
        }

        currentCharacterDirection.SetActive(true); //set gameobject active again
        directionLastFrame = direction; //set the new direction to check for
    }

    currentCharacterDirection.GetAnimator().SetBool("Moving", playerMoving);
}

Setting aside that, your solution seems ok to me (although I don't know that asset's implementation). Hope this helps.

\$\endgroup\$
  • \$\begingroup\$ Some great stuff! Makes it a lot prettier :) \$\endgroup\$ – Green_qaue Nov 18 '17 at 20:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.