0
\$\begingroup\$

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:

ThirdPersonMovement.cs |

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);
            }
        }
    }
}

A video showing my problem

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:

  1. I tried changing the 'If' statement on line 26 to say if (!isWalking && (forwardPressed || leftPressed || rightPressed || backwardPressed)) { 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.
  2. 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. I am still fairly new to Unity and Programming so forgive me please if I overlook something.

\$\endgroup\$
  • \$\begingroup\$ Did you try bool isWalking = Input.GetKey("w") | Input.GetKey("a") | Input.GetKey("s") | Input.GetKey("d"); \$\endgroup\$ – Zibelas Jul 29 at 11:48
  • \$\begingroup\$ @Zibelas no, I don't think so. Hold on let me try it. \$\endgroup\$ – Johnny Ray Shumway Jr. Jul 29 at 17:26
  • \$\begingroup\$ @Zibelas OMG it WAS SO SIMPLE :O I can't believe I overlooked that! I guess I was overthinking it. Thanks mate! If you want put that down as an answer, and I will mark it as the answer. \$\endgroup\$ – Johnny Ray Shumway Jr. Jul 29 at 17:35
0
\$\begingroup\$

While not the most elegant solution, you can simply check for all your input keys. | returns true if at least one of the conditions is true.

 bool isWalking = Input.GetKey("w") | Input.GetKey("a") | Input.GetKey("s") | Input.GetKey("d");

Maybe later you want to switch it for your query against the input manager. Hard coded values are usually not best practice and the player won't be able to change his control to arrow keys or joystick.

 bool isWalking = (horizontalInput != 0) | (verticalInput != 0);
| improve this answer | |
\$\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.