2
\$\begingroup\$

I am developing a top down twin stick shooter. I am running into a issue where if I change my character's rotation, the Unity Blend Tree animation does not play the correct animation that corresponds to that relative rotation. For example if my Character is facing north and I walk forward, the animation plays fine, but if I rotate my character 180 degrees (facing south), when I walk forward it will play the backwards animation.

https://media.giphy.com/media/cmx1aOm0UOjCed8MJT/giphy.gif

I believe this is because I am just sending the inputs from the analog stick, and not offsetting the values based on the rotation of the character. I am using 2 floats (horizontal and vertical) to control the blend tree. How can I offset the float values from the input based on the character's local rotation? Current code below,

 void Update()
{
    if (!ReInput.isReady) return; // Exit if Rewired isn't ready. This would only happen during a script recompile in the editor.
    if (player == null) return;
    GetInput();
    Move();
    Look();

}

private void GetInput()
{
    // Get the input from the Rewired Player. All controllers that the Player owns will contribute, so it doesn't matter
    // whether the input is coming from a joystick, the keyboard, mouse, or a custom controller.

    mhorizontal = player.GetAxis("Move Horizontal"); // get input by name or action id
    mvertical = player.GetAxis("Move Vertical");


    lHorizontal = player.GetAxis("Look Horizontal");
    lVertical = player.GetAxis("Look Vertical");
    //fire = player.GetButtonDown("Fire");
}

void Move()
{

    if (mhorizontal != 0 && mvertical != 0)
    {
        Vector3 rightMovement = right * moveSpeed * Time.deltaTime * mhorizontal;
        Vector3 upMovement = forward * moveSpeed * Time.deltaTime * mvertical;
        //Vector3 heading = Vector3.Normalize(rightMovement + upMovement);

        // transform.forward = heading;
        transform.position += rightMovement;
        transform.position += upMovement; animator.SetFloat("Vertical", mvertical, 0.1f, Time.deltaTime);
        animator.SetFloat("Horizontal", mhorizontal, 0.1f, Time.deltaTime);
    }

}

void Look()
{
    if (lVertical != 0 && lHorizontal != 0)
    {
        float cameraFacing = Camera.main.transform.eulerAngles.y;
        Vector3 inputVector = new Vector3(lHorizontal, 0, lVertical);
        Vector3 turnedInputVector = Quaternion.Euler(0, cameraFacing, 0) * inputVector;
        transform.LookAt(turnedInputVector + transform.position);


    }

}
\$\endgroup\$
1
\$\begingroup\$

Ok, I found a pretty simple solution. I just needed to rotate/offset the X,Y input with the X/Y values from the player's and Camera's Y rotation. Below is my solution:

    void Move()
{

    if (mhorizontal != 0 && mvertical != 0)
    {
        Vector3 rightMovement = right * moveSpeed * Time.deltaTime * mhorizontal;
        Vector3 upMovement = forward * moveSpeed * Time.deltaTime * mvertical;
        //Vector3 heading = Vector3.Normalize(rightMovement + upMovement);

        // transform.forward = heading;
        transform.position += rightMovement;
        transform.position += upMovement;

    }

    Direction.x = mhorizontal;
    Direction.y = mvertical;
    Direction = Rotate(Direction, transform.rotation.eulerAngles.y);
    //Direction =Quaternion.AngleAxis(-45, Vector3.up) * Direction;
    print("Direction is: " + Direction);
  //  Direction = Quaternion.Euler(0, transform.rotation.eulerAngles.y , 0) * Direction;

    animator.SetFloat("Vertical", Direction.y, animationDamp, Time.deltaTime);
    animator.SetFloat("Horizontal", Direction.x, animationDamp, Time.deltaTime);
}

public Vector2 Rotate(Vector2 v, float degrees)
{
    return Quaternion.Euler(0, 0, (degrees + -Camera.main.transform.rotation.eulerAngles.y)) * v;

}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.