Click here to Skip to main content
15,884,938 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I followed this tutorial on youtube: Unity3D. Top-down 8 directions movement - YouTube[^]. It took me a while but I've almost converted from movement by arrows to mouse touch . but now I have this problem, there's flickering that occurs when the character stops moving. I looked at the link he sent me but it doesn't work. Please look at this video to show you what I am talking about: My unity problem - YouTube[^]. Does anyone knows how to stop the flickering that occurs when the character stops moving? This is my code:

C++
private Animator anim;
 public float speed = 15f;
 private Vector3 target;
 private bool touched;


 void Start () {
     target = transform.position;
     anim = GetComponent<Animator> ();
 }

 void Update () {
     touched = true;
     if (Input.GetMouseButtonDown (0)) {
         Vector3 mousePosition = Input.mousePosition;
         mousePosition.z = 10; // distance from the camera
         target = Camera.main.ScreenToWorldPoint(mousePosition);
         target.z = transform.position.z;
     }



         var movementDirection = (target - transform.position).normalized;

         if (movementDirection.x != 0 || movementDirection.y != 0) {
             anim.SetBool("walking" , true);
             anim.SetFloat("SpeedX" , movementDirection.x);
             anim.SetFloat("SpeedY" , movementDirection.y);

             Vector2 movement = new Vector2(
                 speed * movementDirection.x ,
                 speed * movementDirection.y);
             movement *= Time.deltaTime;
             transform.Translate(movement);

             if (movementDirection.x < 0) {
                 anim.SetFloat("LastMoveX" , -1f);
             }
             else if (movementDirection.x > 0) {
                 anim.SetFloat("LastMoveX" , 1f);
             }
             else {
                 anim.SetFloat("LastMoveX" , 0f);
             }
             if (movementDirection.y > 0) {
                 anim.SetFloat("LastMoveY" , 1f);
             }
             else if (movementDirection.y < 0) {
                 anim.SetFloat("LastMoveY" , -1f);
             }
             else {
                 anim.SetFloat("LastMoveY" , 0f);
             }
         } else {
         touched = false;
         anim.SetBool("walking" , false);
     }
 }


What I have tried:

I have tried the following:
https://josejimenez.info/blog/unity3d-top-down-8-direction-movement.html

I've Tried checking out what happens if I add something like

if (movementDirection.x != 0 || movementDirection.y != 0) {
anim.SetFloat("SpeedX", movementDirection.x);
anim.SetFloat("SpeedY", movementDirection.y);
}

and

if (movementDirection.x != 0 || movementDirection.y != 0) {
float rot_z = Mathf.Atan2 (movementDirection.y, movementDirection.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler (0f, 0f, rot_z);
}

as well as
transform.rotation = Quaternion.Euler (0f, 0f, rot_z - 90)
Posted
Updated 17-Apr-16 3:23am

1 solution

You need a dead zone on your Animation transitions make them > 0.1f NOT > 0f you are getting jitter. Hold focus on the character in the object inspector and watch the animator editor transitions.

This is the patch to your code but this is not the proper fix which I will explain next
if (movementDirection.x < 0.1f) {
  anim.SetFloat("LastMoveX" , -1f);
} else if (movementDirection.x > 0.1f) {
  anim.SetFloat("LastMoveX" , 1f);
} else {
  anim.SetFloat("LastMoveX" , 0f);
}
 
if (movementDirection.y < 0.1f) {
  anim.SetFloat("LastMoveY" , -1f);
} else if (movementDirection.y > 0.1f) {
  anim.SetFloat("LastMoveY" , 1f);
} else {
  anim.SetFloat("LastMoveYX" , 0f);
}


You can do what this code is doing properly just sending it out to the animator control untouched

anim.SetFloat("LastMoveX" , movement.x);
anim.SetFloat("LastMoveY" , movement.y);

Now on the transitions (the "Arrows" between the states) in the animator control change to things like >0.1f and <-0.1f

There is no need to restrict yourself to 0-1 the value passed out to the animator is a float and it can be negative. Basically you have code doing what is much better and simpler to do out at the animator.

So out at the animator editor on those arrows between states change them
Idle state transitions
LastMoveX < -0.1f transition to walking left
LastMoveX > 0.1f transition to walking right

Walk left state transition dropback to idle
LastMoveX > -0.1f transition to idle

Walk right state transition dropback to idle
LastMoveX < 0.1f transition to idle

Organize that on the animator like you are supposed to and your code becomes totally redundant and is not needed.
 
Share this answer
 
v4
Comments
wasicool2 17-Apr-16 19:56pm    
I'm sorry I don't get what you mean by
Idle state transitions
LastMoveX < -0.1f transition to walking left
LastMoveX > 0.1f transition to walking right

Walk left state transition dropback to idle
LastMoveX > -0.1f transition to idle

Walk right state transition dropback to idle
LastMoveX < 0.1f transition to idle

could you show me by an image or something, thank you for replying.
leon de boer 17-Apr-16 23:04pm    
These things on the animator screen are called state transitions
http://pasteboard.co/gGdYiCL.jpg

I am going to select the idle to walk backwards one (Equivalent to your walk left .. X-)
I want you to notice the condition value I have used less than -0.1f
http://pasteboard.co/gGp7zVc.jpg

Now lets look at the walk backwards to idle transition
This will have a condition of > -0.1f
http://pasteboard.co/gGxHZAn.jpg

I wont bother showing you but the transition to walk forward is >0.1f

Do you get what we are doing creating a range on our animator variable like you did in code and here they are

-Infinity <-----------------------> -0.1f Means walking backwards

-0.1f <---------0----------> 0.1f Means idle or not moving

0.1f <-----------------------> +Infinity Means walking forward


By simply organizing the animator properly your code becomes completely redundant and you just send the raw value
anim.SetFloat("LastMoveX", movement.x);

So on your game you need 3 animations walk left, walk right and an idle. Then you simply set the transitions
between them and the condition values out on the animator and you are done ... NO CODE required.

It has been like this since Unity version 4.6 and the new animator, so wherever you got the code
from is very old and predates that.

So that is the modern way to do the same thing with no code required :-)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900