How would I have multiple keys control one bool in the Animator Control?

Hello everyone, I have been working on an update to my game. I want to add a Third Person Character Controller. I have the basic Third Person Character Controller and a basic script that works with the Animator Controller to change the state to “isWalking” when the player presses the ‘W’ key. Here is the code so far:

animationStateController.cs |

using UnityEngine;

public class animationStateController : MonoBehaviour
{
    Animator animator; // References the Animator component.
    int isWalkingHash; // Variable for the simplification of the 'If' statements in void update.
    int isRunningHash; // Variable for the simplification of the 'If' statements in void update.

    // Start is called before the first frame update
    void Start()
    {
        animator = GetComponent<Animator>(); // Get's the animator component from the attached character.
        isWalkingHash = Animator.StringToHash("isWalking"); // Converts the string "isWalking" (the name of the bool in the Animator Controller) to a simpler data type.
        isRunningHash = Animator.StringToHash("isRunning"); // Converts the string "isRunning" (the name of the bool in the Animator Controller) to a simpler data type.
    }

    // Update is called once per frame
    void Update()
    { 
        bool forwardPressed = Input.GetKey("w"); // Set's the bool "forwardPressed" to equal the "W" key.
        bool runPressed = Input.GetKey("left shift"); // Set's the bool "runPressed" to equal the "Left Shift" key.
        bool isWalking = animator.GetBool(isWalkingHash); // Set's the bool "isWalking" to equal the "isWalkingHash" integer.
        bool isRunning = animator.GetBool(isRunningHash); // Set's the bool "isRunning" to equal the "isRunningHash" integer.
       
        // If the player is not walking and the 'W' key is pressed then:
        if (!isWalking && forwardPressed)
        {
            // Set the "isWalking" bool to true.
            animator.SetBool(isWalkingHash, true);
        }
        // If the player is walking and the 'W' key is not pressed then:
        if (isWalking && !forwardPressed)
        {
            // Set the "isWalking" bool to false.
            animator.SetBool(isWalkingHash, false);
        }

        // If the player is not running and the 'W' and the 'Left Shift' keys are pressed then:
        if (!isRunning && (forwardPressed && runPressed))
        {
            // Set the "isRunning" bool to true.
            animator.SetBool(isRunningHash, true);
        }
        // If the player is running and the 'W' and the 'Left Shift' keys are not pressed then:
        if (isRunning && (!forwardPressed || !runPressed))
        {
            // Set the "isRunning" bool to false.
            animator.SetBool(isRunningHash, false);
        }
    }
}

My question is how would I use the ‘W’, ‘A’, ‘S’, and ‘D’ keys to control the books “isWalking” all at once? Like I can move forward walking and yes that is good, but I have a ThirdPersonCamera and Control script. Here is the ThirdPersonControl script below, it only covers the movement of the player using the keyboard. Camera movement is done with Cinemachine:

using UnityEngine;

public class ThirdPersonMovement : MonoBehaviour
{
    /// <summary>
    /// controller - The reference to the Character Controller component attached to the "ThirdPersonController" Game Object.
    /// cam - References the Main Camera.
    /// speed - The walking speed of the player.
    /// runSpeed - The running speed of the player.
    /// turnSmoothTime - The time it takes to smooth the player rotation.
    /// turnSmoothVelocity - The smoothing velocity for the Atan2 used later.
    /// </summary>
    public CharacterController controller;
    public Transform cam;
    public float speed = 4f;
    public float runSpeed = 8f;
    public float turnSmoothTime = 0.1f;
    float turnSmoothVelocity;

    // Update is called once per frame
    void Update()
    {
        /// <summary>
        /// horizontalInput get's the Raw Horizontal Input, this way we don't get any type of input smoothing.
        /// verticalInput get's the Raw Vertical Input, this way we don't get input smoothing.
        /// heading Is the direction the player will move in, basically.
        /// </summary>
        float horizontalInput = Input.GetAxisRaw("Horizontal");
        float verticalInput = Input.GetAxisRaw("Vertical");
        Vector3 heading = new Vector3(horizontalInput, 0f, verticalInput).normalized;

        /// <summary>
        /// Below are two bools for determining whether or not the player is walking or is running.
        /// </summary>
        bool isWalking = Input.GetKey("w");
        bool isRunning = Input.GetKey("left shift");

        // If the direction of the player has a value greater than or equal to 0.1f then:
        if (heading.magnitude >= 0.1f)
        {
            /// <summary>
            /// Returns the arc tangent of the values assigned to 'X' and 'Y'. This will equal the float variable "targetAngle".
            /// Mathf.Rad2Deg converts the radians (the number given by the previous equation) to degrees.
            /// </summary>
            float targetAngle = Mathf.Atan2(heading.x, heading.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
            // Assigns the values and calculates smoothing.
            float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);

            // Calculates the rotation of the player than assigns the value to the players Transform Rotation.
            transform.rotation = Quaternion.Euler(0f, angle, 0f);
            // Assigns moveDir the information needed to make the player move in the cameras orientation.
            Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
            // Move the "controller" towards the heading multiplied by speed multiplied by Time.deltaTime;. Time.deltaTime makes the movement frame rate independent.
            controller.Move(moveDir.normalized * speed * Time.deltaTime);

            // If both bools are true then:
            if (isRunning && isWalking)
            {
                // Increase the speed to equal the 'runSpeed' variable.
                controller.Move(moveDir.normalized * runSpeed * Time.deltaTime);
            }
        }
    }
}

The above video demonstrates the problem. I can walk perfectly fine forward, but if I try and walk left, right, or backward I get nothing. I tried multiple things previously. None of which worked. Here is what I have tried:

  • I tried changing the ‘If’ statement on line 26 to say if (!isWalking && (forwardPressed || leftPressed || rightPressed || backwardPressed)) {. Yes, I added the extra variables as well, but the result I received was the animator controller switching quickly between Idle and Walk. I also added to line 32 respectively.
  • I searched for tutorials, all of which (that I found) only dealt with singular animations such as how to go from idle to crouch.

I wish I could remember exactly what else I have tried, but I can’t remember that. Any help with this would be gladly appreciated. Thank you for taking the time to read this.

This turned out to be the answer, I asked the question on stack exchange, shout out to Zibelas of game dev stack exchange.

2 Likes

hayatımı kurtardın