When I don’t use Time.deltaTime, my character moves freely, but when I put it on it walks and runs in place and doesn’t jump. The following is from a tutorial on YouTube by IheartGameDev so please do not ask me why things are used the way they are. My main problem is trying to get the jump animation to work like the walking and running do. To try and fix this I take off TdT and the character moves around the screen and lifts in the air but “jump” doesn’t animate, so I put TdT back in the code to see if this might fix this, but like I said the character just runs and walks in place and barely makes a gesture like it’s jumping. Please do not respond if your only answer is to google it, because I have exhausted that option. Thank you.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class AnimationAndMovementController : MonoBehaviour
{
PlayerInput playerInput;
CharacterController characterController;
Animator animator;
int isWalkingHash;
int isRunningHash;
Vector2 currentMovementInput;
Vector3 currentMovement;
Vector3 currentRunMovement;
bool isMovementPressed;
bool isRunPressed;
float rotationFactorPerFrame = 15.0f;
float runMultiplier = 3.0f;
int zero = 0;
float gravity = -9.8f;
float groundedGravity = -.05f;
bool isJumpPressed = false;
float initialJumpVelocity;
float maxJumpHeight = 4.0f;
float maxJumpTime = .75f;
bool isJumping = false;
int isJumpingHash;
bool isJumpAnimating = false;
void Awake()
{
playerInput = new PlayerInput();
characterController = GetComponent<CharacterController>();
animator = GetComponent<Animator>();
isWalkingHash = Animator.StringToHash("isWalking");
isRunningHash = Animator.StringToHash("isRunning");
isJumpingHash = Animator.StringToHash("isJumping");
playerInput.CharacterControls.Move.started += onMovementInput;
playerInput.CharacterControls.Move.canceled += onMovementInput;
playerInput.CharacterControls.Move.performed += onMovementInput;
playerInput.CharacterControls.Run.started += onRun;
playerInput.CharacterControls.Run.canceled += onRun;
playerInput.CharacterControls.Jump.started += onJump;
playerInput.CharacterControls.Jump.canceled += onJump;
setupJumpVariables();
}
void setupJumpVariables()
{
float timeToApex = maxJumpTime / 2;
gravity = (-2 * maxJumpHeight) / Mathf.Pow(timeToApex, 2);
initialJumpVelocity = (2 * maxJumpHeight) / timeToApex;
}
void handleJump()
{
if (!isJumping && characterController.isGrounded && isJumpPressed)
{
animator.SetBool("isJumpingHash", true);
isJumpAnimating = true;
isJumping = true;
currentMovement.y = initialJumpVelocity * 1.5f;
currentRunMovement.y = initialJumpVelocity * 1.5f;
}
else if (!isJumpPressed && isJumping && characterController.isGrounded)
{
isJumping = false;
}
}
void onJump(InputAction.CallbackContext context)
{
isJumpPressed = context.ReadValueAsButton();
Debug.Log(isJumpPressed);
}
void onRun(InputAction.CallbackContext context)
{
isRunPressed = context.ReadValueAsButton();
}
void handleRotation()
{
Vector3 positionToLookAt;
positionToLookAt.x = currentMovement.x;
positionToLookAt.y = 0.0f;
positionToLookAt.z = currentMovement.z;
Quaternion currentRotation = transform.rotation;
if (isMovementPressed)
{
Quaternion targetRotation = Quaternion.LookRotation(positionToLookAt);
transform.rotation = Quaternion.Slerp(currentRotation, targetRotation, rotationFactorPerFrame);
}
}
void onMovementInput(InputAction.CallbackContext context)
{
currentMovementInput = context.ReadValue<Vector2>();
currentMovement.x = currentMovementInput.x;
currentMovement.z = currentMovementInput.y;
currentRunMovement.x = currentMovementInput.x * runMultiplier;
currentRunMovement.z = currentMovementInput.y * runMultiplier;
isMovementPressed = currentMovementInput.x != 0 || currentMovementInput.y != 0;
}
void handleAnimation()
{
bool isWalking = animator.GetBool(isWalkingHash);
bool isRunning = animator.GetBool(isRunningHash);
if (isMovementPressed && !isWalking)
{
animator.SetBool(isWalkingHash, true);
}
else if (!isMovementPressed && isWalking)
{
animator.SetBool(isWalkingHash, false);
}
if ((isMovementPressed && isRunPressed) && !isRunning)
{
animator.SetBool(isRunningHash, true);
}
else if ((!isMovementPressed || !isRunPressed) && isRunning)
{
animator.SetBool(isRunningHash, false);
}
}
void handleGravity()
{
bool isFalling = currentMovement.y <= 0.0f || !isJumpPressed;
float fallMultiplier = 2.0f;
if (characterController.isGrounded) {
if (isJumpAnimating) {
animator.SetBool("isJumpingHash", false);
isJumpAnimating = false;
}
currentMovement.y = groundedGravity * Time.deltaTime;
currentRunMovement.y = groundedGravity * Time.deltaTime;
}else if (isFalling) {
float previousYVelocity = currentMovement.y;
float newYVelocity = currentMovement.y + (gravity * fallMultiplier * Time.deltaTime);
float nextYVelocity = (previousYVelocity + newYVelocity) * .5f;
currentMovement.y = nextYVelocity;
currentRunMovement.y = nextYVelocity;
} else {
float previousYVelocity = currentMovement.y;
float newYVelocity = currentMovement.y + (gravity);
float nextYVelocity = (previousYVelocity + newYVelocity) * .5f;
currentMovement.y = nextYVelocity;
currentRunMovement.y = nextYVelocity;
}
}
// Update is called once per frame
void Update()
{
handleRotation();
handleAnimation();
if (isRunPressed)
{
characterController.Move(currentRunMovement * Time.deltaTime);
}
else
{
characterController.Move(currentMovement * Time.deltaTime);
}
handleGravity();
handleJump();
}
void OnEnable()
{
playerInput.CharacterControls.Enable();
}
void OnDisable()
{
playerInput.CharacterControls.Disable();
}
}