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. Dismiss Notice

Question Calculate movement vector relative to aim in order to make strafe animations

Discussion in 'Scripting' started by Vohry, Jul 13, 2023.

  1. Vohry

    Vohry

    Joined:
    Jan 11, 2020
    Posts:
    3
    SOLVED - my answer is below

    Hi,
    I am making 3D top down shooter in Unity and I am facing a problem. Camera is fixed and is not rotating, so when you press left button it will rotate the player and move forwards to left. It is working well, but problem is when player is aiming. In my game player has ability to aim while holding right mouse button. I want to make strafe animations while aiming. I have created this blend tree in animator:

    upload_2023-7-13_8-41-31.png

    I have two parameters there: AimingWalkHorizontal and AimingWalkVertical. When the values are [1,0] it will play strafe right animation.

    I have two Vectors. One for movement and one for aiming:

    Code (CSharp):
    1. Vector3 movementVector = new Vector3(_movementVector.x, 0, _movementVector.y);
    2. Vector3 aimingDirection = new Vector3((MouseWorldPosition - PlayerController.PlayerObj.transform.position).x, 0, (MouseWorldPosition - PlayerController.PlayerObj.transform.position).z);
    And I want to achieve this:

    upload_2023-7-13_8-42-49.png

    How can I get this relative movement Vector in order to feed it to animator?

    Code (CSharp):
    1. PlayerController.Animator.SetFloat("AimingWalkHorizontal", /* ??? */);
    2. PlayerController.Animator.SetFloat("AimingWalkVertical", /* ??? */);
    Thank you
     
    Last edited: Jul 13, 2023
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,844
    Are you rotating a transform to point towards the player is aiming? Then just use
    transform.right
    to get a perpendicular direction (assuming the player is facing towards the transform forward direction), which you can fed into your animator.

    Otherwise if you are generating a direction the player is facing in, you can use
    Vector.Cross
    to generate a perpendicular one.
     
  3. Yuchen_Chang

    Yuchen_Chang

    Joined:
    Apr 24, 2020
    Posts:
    105
    If your aiming would be the same as your character's rotation, you can use Transform.InverseTransformDirection(Vector3), which transforms a direction from world space to your character's local space. Then you can take the x,z value out and put in the animator.
     
  4. Vohry

    Vohry

    Joined:
    Jan 11, 2020
    Posts:
    3
    Problem is that I cannot just use perpendicular Vector using transform.right, because it was just example. Player can also aim same direction or diagonal and so on...
     
  5. Vohry

    Vohry

    Joined:
    Jan 11, 2020
    Posts:
    3
    I have finally solved it by calculating clockwise angle between movement and aim vector. Than I am converting angle to normalized vector that is pushed to animator.

    Code (CSharp):
    1. Vector3 movementVector = new Vector3(_movementVector.x, 0, _movementVector.y).normalized;
    2. Vector3 aimingDirection = new Vector3((MouseWorldPosition - PlayerController.PlayerObj.transform.position).x, 0, (MouseWorldPosition - PlayerController.PlayerObj.transform.position).z).normalized;
    3.  
    4. // Calculate clockwise angle between movement and aiming direction
    5. float dotProduct = Vector3.Dot(movementVector, aimingDirection);
    6. float crossProductMagnitude = Vector3.Cross(movementVector, aimingDirection).y;
    7. float clockwiseAngle = Mathf.Atan2(crossProductMagnitude, dotProduct) * Mathf.Rad2Deg;
    8.  
    9. // In my game I have ability to rotate camera with middle mouse button, so I have to decrease angle by camera rotation
    10. // If you have fixed camera rotation do not use this line
    11. clockwiseAngle -= CameraController.Instance.CameraObj.transform.eulerAngles.y;
    12.  
    13. // Adjust the angle to be positive (0 to 360 degrees)
    14. clockwiseAngle = (clockwiseAngle + 360) % 360;
    15.  
    16. // Convert angle to normalized vector
    17.  
    18. // Convert to radians
    19. float radians = clockwiseAngle * Mathf.Deg2Rad;
    20.  
    21. // Calculate vector axis
    22. float x = Mathf.Cos(radians);
    23. float z = Mathf.Sin(radians);
    24.  
    25. // Create normalized vector
    26. Vector3 relativeMovement = new Vector3(x, 0f, z).normalized;
    27.  
    28. // Set values to animator
    29. PlayerController.Animator.SetFloat("AimingWalkHorizontal", relativeMovement.z * -1f);
    30. PlayerController.Animator.SetFloat("AimingWalkVertical", relativeMovement.x);