1
\$\begingroup\$

I am very new to Unity and game making and would appreciate if you would cope with me.

I have made a very basic prototype of character animation and movement, however trigger that is supposed to fire animation happens after character already moved. I just can't seem to find a way to fix it as SetTrigger is void and not a Task.

See this video for what I mean

animated gif

The script I am using to fire off animation is the following:

public class Hero : MonoBehaviour {

    public Animator animator;
    public void Down()
    {
        var move = GameObject.Find("Hero").transform.position;
        animator.SetTrigger("moveDown");
        transform.position = Vector3.Lerp(move, move + new Vector3(0, -1f, 0), 1f); 
    }
}

How does one make both movement and animation to sync up and happen simultaneously?

\$\endgroup\$
  • \$\begingroup\$ Have you tried setting "moveDown" as a float? You would have the transition based off "moveDown > 0", and may need to normalise the value, before you set it; but you can also use it as a speed multiplier, so if you intend to move faster, you can make your animation move faster without much more work. \$\endgroup\$ – Gnemlock Jun 6 '17 at 5:35
  • \$\begingroup\$ You can check for input from inside the animator script instead of setting stuff in the animator script from the input. \$\endgroup\$ – John Hamilton Jun 6 '17 at 5:53
  • \$\begingroup\$ Little opinionated side-note: While I find the Unity animation system great for 3d animations, I think it is hopelessly overengineered for 2d games. When you just want to swap out sprites, you will have a much easier time if you just write your own. Especially when all your spritesheets are organized in the same way. \$\endgroup\$ – Philipp Jun 6 '17 at 12:04
2
\$\begingroup\$

You are trying to move the character from one point to another within the single method Down. This is not going to work, because that whole method is executed in a single frame. Vector3.Lerp just by itself doesn't cause a position to change slowly. All it does is calculate a position between two positions and return that as a new vector. This is a tool which can be useful for doing a gradual transition, but just by itself it doesn't do that.

What you should do instead is have Down set the information that the character is walking somewhere and then do the actual position updating in Update.

It should look something like this (untested!):

public class Hero : MonoBehaviour {

    public Animator animator;
    private Vector3 moveDestination;
    private float moveTime = 0.0f;

    private void Start() {
         moveDestination = transform.position;
    }

    public void Down()
    {
        // when the character isn't already moving, move it down
        if (moveTime <= 0.0f) {
            moveDestination = transform.position + new Vector3(0, -1f, 0)
            moveTime = 1.0f;
            animator.SetTrigger("moveDown");
        }
    }

    public void Update() {
          if (moveTime > 0.0f) {
              moveTime -= Time.deltaTime;
              transform.position = Vector3.Lerp(moveDestination, transform.position, moveTime); 

              if (moveTime <= 0.0f) {
                  animator.SetTrigger("idle");
              }
          }
    }
}

Also you need to remove transition duration
Click on transition arrow in Animator window, then in Inspector window expand Settings under Has Exit Time and set both Transition Duration and Transition Offset to 0.

enter image description here

\$\endgroup\$
  • \$\begingroup\$ Hi Philipp, it worked like a charm, thanks. My animation still starts about midway through the motion though... youtube.com/watch?v=WHrr-kOGBPo&feature=youtu.be what would be appropriate mechanism so the movement would start at same time as animation? \$\endgroup\$ – Matas Vaitkevicius Jun 6 '17 at 9:48
  • \$\begingroup\$ @MatasVaitkevicius This might be a problem with a too long exit time in the animation. \$\endgroup\$ – Philipp Jun 6 '17 at 9:49
  • \$\begingroup\$ I have removed exit time completely from both transitions, and did return to the idle on trigger as per your example, and it still delays. Any other 'gut feelings'? \$\endgroup\$ – Matas Vaitkevicius Jun 6 '17 at 9:57
  • \$\begingroup\$ You were right I had to expand settings and change Transition Duration and Offset to 0 and this did it. \$\endgroup\$ – Matas Vaitkevicius Jun 7 '17 at 3:31

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.