Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Unity2D - Make my character face towards movement direction

Discussion in 'Scripting' started by Patahuete, Jul 12, 2020.

  1. Patahuete

    Patahuete

    Joined:
    Jul 21, 2018
    Posts:
    2
    Hey everyone !
    I'm new to Unity, and I'm trying to create my first little game. I did a map, and a character that can move, and even some animations !

    I have one problem, though... When I press wasd, my character goes in one direction, and uses the proper animation, but when I stop pressing the keys, my character isn't facing the direction he was heading to....
    I used 2 blend trees, one with all my idle animations, and one with my walking animations, but when it is supposed to be idling in any direction, it just get stuck and idling with the "Idle_Down" animation... Is there so code that I need to add ?

    Here's my Controller script :

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerMovement : MonoBehaviour
    6. {
    7.     public float moveSpeed = 5f;
    8.  
    9.     public Rigidbody2D rb;
    10.     public Animator animator;
    11.  
    12.     Vector2 movement;
    13.  
    14.     // Update is called once per frame
    15.     void Update()
    16.     {
    17.         // Input
    18.         movement.x = Input.GetAxisRaw("Horizontal");
    19.         movement.y = Input.GetAxisRaw("Vertical");
    20.  
    21.         animator.SetFloat("Horizontal", movement.x);
    22.         animator.SetFloat("Vertical", movement.y);
    23.         animator.SetFloat("Speed", movement.sqrMagnitude);
    24.     }
    25.  
    26.     void FixedUpdate()
    27.     {
    28.         // Movement
    29.  
    30.         rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
    31.     }
    32. }
    33.  
    I understand that it can be confusing, I even myself don't really know how to precisely explain my problem ^^"
     

    Attached Files:

  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,971
    WECOME! Bravo for a good post, with formatted code and a clear description and everything.

    I am going to speculate that the problem is when you come to rest you are supplying 0 and 0 for x and y to your animator parameters.

    When you are going 0 and 0, you're not really facing anywhere, so what you probably want is to leave it facing what it was before you stopped moving, most of the time anyway.

    Try this:

    Put lines 21 and 22 above into an if statement that checks the size of movement and only sets those animator parameters if you are moving at a certain minimum amount, something like this:

    Code (csharp):
    1. if (movement.magnitude > 0.01f)
    2. {
    3.     animator.SetFloat("Horizontal", movement.x);
    4.     animator.SetFloat("Vertical", movement.y);
    5. }
    You still want to leave the speed setter though, so you fully come to a zero animation speed, if that makes a difference in your animation state machine.
     
  3. Zer0Cool

    Zer0Cool

    Joined:
    Oct 24, 2014
    Posts:
    203
    If i understand your problem correct you must save your last movement direction in your controller and pass this direction to your idle blend tree.

    Therefore you must give the idle blend tree other variable names "HorizontalIdle" "VerticalIdle" and only call it if your character is not running. The other variables could be defined like this:

    Code (CSharp):
    1.     Vector2 movementLast;
    2.  
    3.     // Update is called once per frame
    4.     void Update()
    5.     {
    6.         // Input
    7.         movement.x = Input.GetAxisRaw("Horizontal");
    8.         movement.y = Input.GetAxisRaw("Vertical");
    9.         animator.SetFloat("Horizontal", movement.x);
    10.         animator.SetFloat("Vertical", movement.y);
    11.         animator.SetFloat("Speed", movement.sqrMagnitude);
    12.  
    13.         if (movement.x == 0 && movement.y == 0) {
    14.           animator.SetFloat("HorizontalIdle", movementLast.x);
    15.           animator.SetFloat("VerticalIdle", movementLast.y);
    16.         } else {
    17.           animator.SetFloat("HorizontalIdle", 0f);
    18.           animator.SetFloat("VerticalIdle", 0f);
    19.         }
    20.  
    21.         if (movement.x != 0) movementLast.x = movement.x;
    22.         if (movement.y != 0) movementLast.y = movement.y;
    23.  
    24.     }
    Its not perfect at all you should use the velocity of the players rigidbody to drive your animations.
     
    Last edited: Jul 12, 2020
  4. Patahuete

    Patahuete

    Joined:
    Jul 21, 2018
    Posts:
    2
    Thanks !

    It works perfectly fine !

    I really don't like using forums to get help, as I really like to find the solution myself, but I guess I need to recognize when I'm defeated haha

    I'm really having trouble understanding some of the concepts, even when using tutorials... (Thanks Brackeys ^^)