Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question WASD movement, looking at mouse position animation question

Discussion in 'Animation' started by madeer, Jul 27, 2020.

  1. madeer

    madeer

    Joined:
    Aug 2, 2018
    Posts:
    5
    Hi,

    Bottom line I would like to imitate movement of a game like Battlerite.


    3D, WASD movement of character while always looking at the position of the mouse.
    So if the mouse position is on the right side of the character and you would be pressing D the player would have the Walk Forwards animation, if they would be pressing A they would have the Walk Backwards animation.
    If the mouse would be above the player and they would press D they would strafe to the right, if they press S they would walk backwards.

    I am not sure how to approach this. Any help would be very much appreciated. Thank you.

    This is the code i am using, it is from a YouTube tutorial by Broken Knights Games.
    Code (CSharp):
    1. public class Input : MonoBehaviour
    2. {
    3.     public Vector2 InputVector { get; private set; }  
    4.     public Vector2 relativeDirection;
    5.     public Vector3 MousePosition { get; private set; }
    6.  
    7.     float h, v;
    8.  
    9.     Animator anim;
    10.     private void Start()
    11.     {
    12.         anim = GetComponent<Animator>();
    13.     }
    14.     // Update is called once per frame
    15.     void Update()
    16.     {
    17.         h = UnityEngine.Input.GetAxisRaw("Horizontal");
    18.         anim.SetFloat("h", h);
    19.         v = UnityEngine.Input.GetAxisRaw("Vertical");
    20.         anim.SetFloat("v", v);
    21.                
    22.         InputVector = new Vector2(h, v).normalized;
    23.         MousePosition = UnityEngine.Input.mousePosition;              
    24.     }
    25. }
    Code (CSharp):
    1. public class MovementAndRotation : MonoBehaviour
    2. {
    3.     private Input _input;
    4.  
    5.     [SerializeField]
    6.     private bool RotateTowardMouse;
    7.  
    8.     [SerializeField]
    9.     private float MovementSpeed;
    10.     [SerializeField]
    11.     private float RotationSpeed;
    12.  
    13.     [SerializeField]
    14.     private Camera Camera;  
    15.  
    16.     private void Awake()
    17.     {
    18.         _input = GetComponent<Input>();
    19.     }
    20.  
    21.     // Update is called once per frame
    22.     void FixedUpdate()
    23.     {
    24.         var targetVector = new Vector3(_input.InputVector.x, 0, _input.InputVector.y);
    25.         var movementVector = MoveTowardTarget(targetVector);
    26.      
    27.         if (!RotateTowardMouse)
    28.         {
    29.             RotateTowardMovementVector(movementVector);
    30.         }
    31.         if (RotateTowardMouse)
    32.         {
    33.             RotateFromMouseVector();
    34.         }
    35.     }
    36.  
    37.     private void RotateFromMouseVector()
    38.     {
    39.         Ray ray = Camera.ScreenPointToRay(_input.MousePosition);
    40.  
    41.         if (Physics.Raycast(ray, out RaycastHit hitInfo, maxDistance: 300f))
    42.         {
    43.             var target = hitInfo.point;
    44.             target.y = base.transform.position.y;
    45.             transform.LookAt(target);
    46.         }
    47.     }
    48.  
    49.     private Vector3 MoveTowardTarget(Vector3 targetVector)
    50.     {
    51.         var speed = MovementSpeed * Time.deltaTime;
    52.         // transform.Translate(targetVector * (MovementSpeed * Time.deltaTime)); Demonstrate why this doesn't work
    53.         //transform.Translate(targetVector * (MovementSpeed * Time.deltaTime), Camera.gameObject.transform);
    54.  
    55.         targetVector = Quaternion.Euler(0, Camera.gameObject.transform.rotation.eulerAngles.y, 0) * targetVector;
    56.         var targetPosition = transform.position + targetVector * speed;
    57.         transform.position = targetPosition;
    58.        
    59.         return targetVector;
    60.     }
    61.  
    62.     private void RotateTowardMovementVector(Vector3 movementDirection)
    63.     {
    64.         if (movementDirection.magnitude == 0) { return; }
    65.         var rotation = Quaternion.LookRotation(movementDirection);
    66.         transform.rotation = Quaternion.RotateTowards(transform.rotation, rotation, RotationSpeed);
    67.     }
    68. }
     
    Grannyboy likes this.
  2. Antry

    Antry

    Joined:
    Apr 1, 2016
    Posts:
    2
    Hey, it took some time to figure out how to do this myself when I needed it, without having to do all the logic in code and feeding the 'right' orientation to the Animator.

    What I did is make a Blend Tree of Blend Trees (they are all 2D Simple Directional); basically I use blend trees for Orientation of the player
    (MousePosition-PlayerPosition).Normalized
    which gives me hDir and vDir, where I made North, South, West, East.; and then I have Blend Trees who use hInput and vInput which are from
    Input.GetAxis()
    . Now in these trees the correct animation for orientation are done, and voila, that's basically it, it all works.
    Don't forget to put Idle animations in your Input blend tree(s)
     
    crossfirealt22 and Caiquemoa like this.