Home > Enterprise >  Top Down Shooter Animations Unity, how do you get the right directional animations to play when movi
Top Down Shooter Animations Unity, how do you get the right directional animations to play when movi

Time:04-15

i'm not really sure how to phrase the question sorry about that. I have encountered this hurdle while setting up animations on a character for learning a top down character controller (No rigid body) I've seen this question asked on Reddit and unity forums like a decade ago, but I don't really understand their answers.

My problem right now is that I can't find out a way to tell mecanim if the player is moving towards the direction they're facing. For example, if the player is moving left and aiming to the left, the moveForward animation should be played. If the player is moving left but aiming to the right, the moveBackwards animation should be played.

This is the first time i'm posting a question. I am sorry if my formatting is wrong. Here is the code I have, I would greatly appreciate any help.

public class CharacterMovement : MonoBehaviour
{

    private Vector3 velocity;

    private Vector3 PlayerMoveInput;

    Animator animationS;
    [SerializeField] CharacterController characterrController;
    [SerializeField] private float MoveSpeed;
    [SerializeField] private float JumpHeight;
    [SerializeField] private float Gravity = -9.81f;
    

    // Start is called before the first frame update
    void Start()
    {
        animationS = GetComponent<Animator>();

    }

    // Update is called once per frame
    void Update()
    {
        PlayerMoveInput = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical")); //collects the input for the player

        MovePlayer();
        PlayerRotation();

    }

    private void MovePlayer() 
    {
      

        if (characterrController.isGrounded)
        {

            velocity.y = -1f;
        }
        
        if (Input.GetKeyDown(KeyCode.Space) && characterrController.isGrounded) 
        {

            velocity.y = JumpHeight;

        }
        ///
        else
        {
            velocity.y -= Gravity * -2f * Time.deltaTime; 
        }

       
        Vector3 MoveVector = transform.TransformDirection(PlayerMoveInput);

        characterrController.Move(MoveSpeed * Time.deltaTime * MoveVector);

        characterrController.Move(velocity * Time.deltaTime);

        
        float velocityX = Vector3.Dot(PlayerMoveInput, transform.forward);
        float velocityZ = Vector3.Dot(PlayerMoveInput, transform.right);
       

        animationS.SetFloat("velocityX", velocityZ, 0.1f, Time.deltaTime);
        animationS.SetFloat("velocityZ", velocityX, 0.1f, Time.deltaTime);

    }

    void PlayerRotation()
    {

        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;

        Debug.DrawRay(ray.origin, ray.direction, Color.yellow);

        

        if (Physics.Raycast(ray, out hit))
        {
            Vector3 targetPosition = new Vector3(hit.point.x, transform.position.y, hit.point.z);

            Quaternion rotation = Quaternion.LookRotation(targetPosition - transform.position);

            transform.rotation = Quaternion.Lerp(transform.rotation, rotation, Time.deltaTime * 10.0f); 

            

        }
        
    }
}

CodePudding user response:

This isn't the exact implementation that would be used with your code but should give you a good start.

// get the angle between where the player is pointing, and where he is moving
float angle = Vector3.Angle(MoveVector, targetPosition - transform.position);

if (angle < 90f){
    //move forward animation
} else {
    //move back animation
}

I haven't tested this code but the idea is that if the angle between the direction the player is facing and the direction the player is moving is less than 90 degrees, then he is moving forward. Also the variables used here: MoveVector and targetPosition are private so you will need to fix that issue before this method can be implemented.

CodePudding user response:

With mechanim, its very common to have 4 separate float value params in your animator. Two are used for movement info, two are for look direction info. This lets you use blend trees based on those functions that handle alot of the pain, all you need to do is update the values in the animator with the correct ones on each update/lateupdate depending on what you are doing.

This is how my animator params are layed out as well as the locomotion blend tree, I have another on a separate layer just for the head that uses Head left right, and head updown params to, you know, control the head. enter image description here And here is the code (or at least some of it) that sets the values on the animator component enter image description here

EDIT:

Sorry, forgot to mention that the function i call "LerpFloat" on the anim variable is an extention method i defined myself for the animator component, all it does is gets the float value, lerps it, then sets the float value back. It just uses Mathf.Lerp.

  • Related