0
\$\begingroup\$

I am making a simple 2D shooter.

I have my character's body and head as different objects, as I want him to look up/down regardless of the movement. So, I basically use the following script:

public class PlayerHead : MonoBehaviour
{
    public static PlayerHead instance;
    public SpriteRenderer theSR;
    public Sprite netural, down, up;

    private void Start()
    {
        instance = this;
        
    }
    public void Up()
    {
        theSR.sprite = up;
    }

    public void Down()
    {
        theSR.sprite = down;
    }

    public void Netural()
    {
        theSR.sprite = netural;
    }

}

However, the head is also used in the player animations:

enter image description here

This is because head must move with the body during the idle animation (breathing and moving up&down slowly).

I suspect that because of this animation, the sprite of the head is somehow fixed. It does not change in runtime even though I change it manually inside Unity.

How can I make the Animator let me change the sprite?

\$\endgroup\$
  • \$\begingroup\$ Are you looking for sprite animation re-skinning? \$\endgroup\$ – DMGregory Jul 2 at 19:25
  • \$\begingroup\$ @DMGregory Yup! I needed to use the LateUpdate as the Head object is always updated during the animation. \$\endgroup\$ – padawan Jul 2 at 19:33
  • \$\begingroup\$ If you've solved your problem, would you like to post your solution as an Answer below? \$\endgroup\$ – DMGregory Jul 2 at 19:34
  • \$\begingroup\$ You solved my problem :) I wouldn't want to take credit for your solution. \$\endgroup\$ – padawan Jul 2 at 19:46
  • \$\begingroup\$ You'd be doing me a favour. I've never actually done this, so you have working code that you've tested - I don't. So it would take me more time to write a good answer. \$\endgroup\$ – DMGregory Jul 2 at 19:55
1
\$\begingroup\$

Thanks to DM Gregory's comment, I have understood and solved the issue.

Since I am using the Head object in animator, the sprite is updated in every frame. Therefore, even I change it in one frame, it goes back to default in the next one.

This is the right way to do it:

public class PlayerHead : MonoBehaviour
{
    public static PlayerHead instance;
    public SpriteRenderer theSR;
    public Sprite netural, down, up;
    public Sprite current;

    private void Start()
    {
        instance = this;
        
    }

    private void LateUpdate()
    {
        theSR.sprite = current;
    }

    public void Up()
    {
        current = up;
    }

    public void Down()
    {
        current = down;
    }

    public void Netural()
    {
        current = netural;
    }

}

It is importan to use LateUpdate() method because the animations are updated between Update() and LateUpdate().

Credit goes to DMGregory.

| improve this answer | |
\$\endgroup\$

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.