Reputation: 135
I am new to Unity and have been having a hard time adding running and animations (I have the animations and they are set up in animator) to my FPS controller script. Can someone please help me add running and animations? I would be extremely grateful.
Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
Animator anim;
float RotateX;
float RotateY;
public static bool GamePaused;
[SerializeField]
[Header("Game Objects")]
public GameObject Camera;
public GameObject PauseMenu;
public GameObject Player;
[Header("Movement Settings")]
public float WalkSpeed = 5.0f;
public float RunSpeed = 10.0f;
[Header("Rotation Settings")]
public float RorationSpeed;
public float MaxYAxis = 60.0f; // right
public float MinYAxis = -48.0f; // left
public bool Grounded;
private void Start()
{
anim = GetComponent<Animator>();
}
void Update()
{
transform.Translate(Vector3.forward * Input.GetAxis("Vertical") * WalkSpeed * Time.deltaTime);
transform.Translate(Vector3.right * Input.GetAxis("Horizontal") * WalkSpeed * Time.deltaTime);
RotateX += Input.GetAxis("Mouse X") * RorationSpeed;
RotateY += Input.GetAxis("Mouse Y") * RorationSpeed;
RotateY = Mathf.Clamp(RotateY, MinYAxis, MaxYAxis);
Camera.transform.localRotation = Quaternion.Euler(-RotateY, 0f, 0f);
transform.rotation = Quaternion.Euler(0f, RotateX, 0f);
}
}
Here is what I have to trigger the different animations in the animator, but the animation follows through when I release the key rather than switching immediately upon release.
if (Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.A) ||
Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.D) ||
Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.LeftArrow) ||
Input.GetKeyDown(KeyCode.DownArrow) || Input.GetKeyDown(KeyCode.RightArrow))
{
anim.SetBool("IsWalking", true);
}
if (Input.GetKeyUp(KeyCode.W) || Input.GetKeyDown(KeyCode.A) ||
Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.D) ||
Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.LeftArrow) ||
Input.GetKeyDown(KeyCode.DownArrow) || Input.GetKeyDown(KeyCode.RightArrow))
{
anim.SetBool("IsWalking", false);
}
Upvotes: 0
Views: 1880
Reputation: 135
Here is my working script with walking, running, jumping and animation triggers.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
Animator anim;
float RotateX;
float RotateY;
Rigidbody rb;
public static bool GamePaused;
public bool isGrounded;
[SerializeField]
[Header("Game Objects")]
public GameObject Camera;
public GameObject PauseMenu;
public GameObject Player;
[Header("Movement Settings")]
public float DefaultSpeed = 5.0f;
public float WalkSpeed = 5.0f;
public float RunSpeed = 10.0f;
public float jumpForce = 2.5f;
public Vector3 jump;
[Header("Rotation Settings")]
public float RorationSpeed = 3.0f;
public float MaxYAxis = 60.0f;
public float MinYAxis = -48.0f;
private void Start()
{
anim = GetComponent<Animator>();
rb = GetComponent<Rigidbody>();
jump = new Vector3(0.0f, 1.0f, 0.0f);
}
void Update()
{
Rotation();
Movement();
Bool();
if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
rb.AddForce(jump * jumpForce, ForceMode.Impulse);
isGrounded = false;
}
}
void Rotation()
{
RotateX += Input.GetAxis("Mouse X") * RorationSpeed;
RotateY += Input.GetAxis("Mouse Y") * RorationSpeed;
RotateY = Mathf.Clamp(RotateY, MinYAxis, MaxYAxis);
Camera.transform.localRotation = Quaternion.Euler(-RotateY, 0f, 0f);
transform.rotation = Quaternion.Euler(0f, RotateX, 0f);
}
void Movement()
{
transform.Translate(Vector3.forward * Input.GetAxis("Vertical") * WalkSpeed * Time.deltaTime);
transform.Translate(Vector3.right * Input.GetAxis("Horizontal") * WalkSpeed * Time.deltaTime);
if (Input.GetKeyDown(KeyCode.LeftShift))
{
WalkSpeed = RunSpeed;
}
if (Input.GetKeyUp(KeyCode.LeftShift))
{
WalkSpeed = DefaultSpeed;
}
}
void Bool()
{
if (Input.GetKeyDown(KeyCode.W))
{
anim.SetBool("IsWalkingForward", true);
}
if (Input.GetKeyDown(KeyCode.A))
{
anim.SetBool("IsWalkingLeft", true);
}
if (Input.GetKeyDown(KeyCode.S))
{
anim.SetBool("IsWalkingBack", true);
}
if (Input.GetKeyDown(KeyCode.D))
{
anim.SetBool("IsWalkingRight", true);
}
if (Input.GetKeyDown(KeyCode.UpArrow))
{
anim.SetBool("IsWalkingForward", true);
}
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
anim.SetBool("IsWalkingLeft", true);
}
if (Input.GetKeyDown(KeyCode.DownArrow))
{
anim.SetBool("IsWalkingBack", true);
}
if (Input.GetKeyDown(KeyCode.RightArrow))
{
anim.SetBool("IsWalkingRight", true);
}
if (Input.GetKeyUp(KeyCode.W))
{
anim.SetBool("IsWalkingForward", false);
}
if (Input.GetKeyUp(KeyCode.A))
{
anim.SetBool("IsWalkingLeft", false);
}
if (Input.GetKeyUp(KeyCode.S))
{
anim.SetBool("IsWalkingBack", false);
}
if (Input.GetKeyUp(KeyCode.D))
{
anim.SetBool("IsWalkingRight", false);
}
if (Input.GetKeyUp(KeyCode.UpArrow))
{
anim.SetBool("IsWalkingForward", false);
}
if (Input.GetKeyUp(KeyCode.LeftArrow))
{
anim.SetBool("IsWalkingLeft", false);
}
if (Input.GetKeyUp(KeyCode.DownArrow))
{
anim.SetBool("IsWalkingBack", false);
}
if (Input.GetKeyUp(KeyCode.RightArrow))
{
anim.SetBool("IsWalkingRight", false);
}
}
void OnCollisionStay()
{
isGrounded = true;
}
void OnCollisionExit()
{
isGrounded = false;
}
}
Upvotes: -1
Reputation: 175
What I can suggest is that you use the horizontal and vertical axes, rather than hard-coded key presses.
More specifically, first of all (if you have not already) in the animator window create an idle state and a walking animation state. You will need somehow to transition between the two states. To do that you will need to create a new bool parameter (let's name it "isWalking" as you did) and create a new condition between the idle and the walking state. For example, set to transition between "idle" to "walking" when isWalking is true and transition between "walking" to "idle" when isWalking is false.
Now in your PlayerController script in the update or fixed update you can add the following code
horizontalMovement = Input.GetAxis("Horizontal");
verticalMovement = Input.GetAxis("Vertical");
//normalize vector so movement in two axis simultanesly is balanced.
moveDirection = (horizontalMovement * transform.right + verticalMovement * transform.forward).normalized;
/* based on your code although a rigid body solution or character controller would have been more robust */
transform.Translate(moveDirection * WalkSpeed * Time.deltaTime);
if (horizontal != 0 || vertical != 0)
{
animator.setFloat("isWalking",true);
}
else
{
animator.setFloat("isWalking",false);
}
However this solution is working is implemented based on the code you provided. If you want to switch in a more robust and easy to maintain script you can use this free controller that uses a rigidbody and has animations already installed and working.
https://github.com/PanMig/First-Person-Unity-Camera
Upvotes: 2