0
\$\begingroup\$

Using Unity 2019.4.1f1 Personal.

Unity Animation Controller nodes

I have the above Animation Controller. When only walking in one direction at a time and when you stop you stay facing that direction, this works as planned.

Successfully walking pokemon trainer

All of the transitions do not have an exit time and have a fixed duration of 0. I don't know what info to give as this is the first time I've used animation. Let me know and I'll add relevant details.

Here's my update function that updates the variables in the animator:

void Update() {
  float h = Input.GetAxisRaw("Horizontal");
  float v = Input.GetAxisRaw("Vertical");

  animator.SetFloat("Horizontal", h);
  animator.SetFloat("Vertical", v);

  if (Mathf.Abs(v) < Mathf.Abs(h)) {
    // flips the renderer to reuse other handed image
    spriteRenderer.flipX = h > 0;
  }

  // no actual movement until I figure this out
}

What I'm experiencing that I want to fix is when running diagonally:

Broken diagonal movement

It seems that when walking diagonally then the animator variables for Horizontal and Vertical are both either 1 or -1 and this causes the alternating of the sprites. What I'd like to happen is that the state machine would deterministically pick either N/S sprites or E/W sprites when moving diagonally. Turning on "Can Transition To Self" seems to properly pick a direction and stick to it but it fails to animate when only moving in a single direction. It looks like it's constantly transitioning to itself which starts over the cycle so I've left that unchecked on all transitions.

I'm not sure what the best way to fix this is. Most attempts I've tried so far complicate the state machine to the point it's unmaintainable. I also couldn't find anything about introducing priorities in a way that fixed the jitter.

What's the idiomatic Unity way to achieve clean diagonal movement in 2D?

\$\endgroup\$
3
  • \$\begingroup\$ Can you show us the conditions on one of your diagonal transition arrows, and one of the cardinal direction transition arrows for contrast? My guess is that the criteria that satisfy the diagonal transition also satisfy the criteria for two of your cardinal transitions, leading the transition from "Any State" to continually fire between them. \$\endgroup\$
    – DMGregory
    Jun 28 '20 at 2:03
  • \$\begingroup\$ @DMGregory I do not have states for diagonal movement. What you describe sounds like what's happening. I was hopeful to reuse the existing N/S or E/W (I really don't care which directions are favored). Since all the conditions are a list of "<Variable> greater/less than <Value>" I assumed they were or logic and wouldn't help. If I can't define "condition AND condition" how would I even write a diagonal transition? \$\endgroup\$ Jun 28 '20 at 3:00
  • \$\begingroup\$ "I assumed they were or logic" Rather than assume, did you stop to experiment, or check the docs? "If your transition has one or more conditions, the conditions must all be met before the transition is triggered." Have you tried adding an extra condition to your horizontal state transitions to keep them from triggering when your vertical states are active? \$\endgroup\$
    – DMGregory
    Jun 28 '20 at 10:42
1
\$\begingroup\$

The cause

Now you have selected that walk in some direction can be triggered from Any State. Thus, if you have vertical = 1 and horizontal = 1 in WalkingNorth state, your transition to WalkingEast is triggered (it meets the condition for horizontal = 1) and vice versa (transition to WalkingNorth is triggered when in WalkingEast state because of vertical = 1).

Solution

Consider changing your animation state transitions, so that Entry points to IdleSouth - this will be your initial state. Then, make transitions from every Idle_ state to every Walking_ state based on triggers. Leave Walking_ -> Idle_ transitions intact. This will prevent you from going from WalkingNorth to WalkingEast when horizontal = 1 and vertical = 1.

\$\endgroup\$
0
\$\begingroup\$

You can add a condition as when any one of the input is not 0 then randomly assign a value to the animator.

If(h==1){ If(y==1){ Anim.SetFloat("Horizontal",0); Anim.SetFloat("Vertical",1); }else if(y==-1){ Anim.SetFloat("Horizontal",0); Anim.SetFloat("Vertical",-1); }}

Same could be done with h = -1

\$\endgroup\$
4
  • \$\begingroup\$ This answer would be better if it walked through the steps of how to do this, or showed an example in the inspector. \$\endgroup\$
    – DMGregory
    Jun 29 '20 at 10:54
  • \$\begingroup\$ Hmm. This could be better \$\endgroup\$ Jun 30 '20 at 6:31
  • \$\begingroup\$ You probably want to add the conditionals in the animation transitions in the controller, not in the code. \$\endgroup\$
    – DMGregory
    Jun 30 '20 at 10:08
  • \$\begingroup\$ Just add them in the script provided in the question above. \$\endgroup\$ Jun 30 '20 at 10:55

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.