Код: Выделить всё
using UnityEngine;
using UnityEngine.InputSystem;
public class AnimationAndMovementController : MonoBehaviour
{
private static readonly int IsWalking = Animator.StringToHash("isWalking");
private static readonly int IsRunning = Animator.StringToHash("isRunning");
private InputSystem_Actions playerInput;
private CharacterController characterController;
private Animator animator;
private Camera mainCamera;
private Vector2 currentMovementInput;
private Vector3 currentMovement;
private Vector3 currentRunMovement;
private bool isMovementPressed;
private bool isRunPressed;
private float rotationFactorPerFrame = 15.0f;
private float runMultiplier = 1.8f;
private float speed = 3.0f;
private int zero = 0;
private bool isJumpPressed = false;
private float initialJumpVelocity;
private float maxJumpHeight = 1.0f;
private float maxJumpTime = 0.75f;
private bool isJumping = false;
private float groundedGravity = -.05f;
private float gravity = -9.8f;
private void Awake()
{
playerInput = new InputSystem_Actions();
characterController = GetComponent();
animator = GetComponent();
mainCamera = Camera.main;
playerInput.Player.Move.started += OnMovementInput;
playerInput.Player.Move.canceled += OnMovementInput;
playerInput.Player.Move.performed += OnMovementInput;
playerInput.Player.Sprint.started += OnRun;
playerInput.Player.Sprint.canceled += OnRun;
playerInput.Player.Jump.started += OnJump;
playerInput.Player.Jump.canceled += OnJump;
SetupJumpVariables();
}
private void SetupJumpVariables()
{
float timeToApex = maxJumpTime / 2;
gravity = (-2 * maxJumpHeight) / Mathf.Pow(timeToApex, 2);
initialJumpVelocity = (2 * maxJumpHeight) / timeToApex;
}
private void HandleJump()
{
if (characterController.isGrounded && isJumpPressed && !isJumping)
{
isJumping = true;
currentMovement.y = initialJumpVelocity * .5f;
currentRunMovement.y = initialJumpVelocity *.5f;
}
else if (isJumping && !isJumpPressed && characterController.isGrounded)
{
isJumping = false;
}
}
private void OnJump(InputAction.CallbackContext context)
{
isJumpPressed = context.ReadValueAsButton();
}
private void OnRun(InputAction.CallbackContext context)
{
isRunPressed = context.ReadValueAsButton();
}
private void OnMovementInput(InputAction.CallbackContext context)
{
currentMovementInput = context.ReadValue();
isMovementPressed = currentMovementInput.x != 0 || currentMovementInput.y != 0;
}
private void UpdateMovement()
{
Vector3 forward = mainCamera.transform.forward;
Vector3 right = mainCamera.transform.right;
forward.y = 0f;
right.y = 0f;
forward.Normalize();
right.Normalize();
currentMovement = forward * currentMovementInput.y + right * currentMovementInput.x;
currentRunMovement = currentMovement * runMultiplier;
}
private void HandleRotation()
{
Vector3 positionToLookAt;
positionToLookAt.x = currentMovement.x;
positionToLookAt.y = zero;
positionToLookAt.z = currentMovement.z;
Quaternion currentRotation = transform.rotation;
if (isMovementPressed)
{
Quaternion targetRotation = Quaternion.LookRotation(positionToLookAt);
transform.rotation = Quaternion.Slerp(currentRotation, targetRotation, rotationFactorPerFrame * Time.deltaTime);
}
}
private void HandleGravity()
{
bool isFalling = currentMovement.y < 0.0f || !isJumpPressed;
float fallMultiplier = 2.0f;
if (characterController.isGrounded)
{
currentMovement.y = groundedGravity;
currentRunMovement.y = groundedGravity;
}
else if (isFalling)
{
float previousY = currentMovement.y;
float newY = currentMovement.y + (gravity * fallMultiplier * Time.deltaTime);
float nextY = Mathf.Max((previousY + newY) * .5f, -20f);
currentMovement.y += nextY;
}
else
{
float previousY = currentMovement.y;
float newY = currentMovement.y + gravity * Time.deltaTime;
float nextY = (previousY + newY) * .5f;
currentMovement.y += nextY;
currentRunMovement.y += nextY;
}
}
private void HandleAnimation()
{
bool isWalking = animator.GetBool(IsWalking);
bool isRunning = animator.GetBool(IsRunning);
if (isMovementPressed && !isWalking)
{
animator.SetBool(IsWalking, true);
}
else if (!isMovementPressed && isWalking)
{
animator.SetBool(IsWalking, false);
}
if ((isMovementPressed && isRunPressed) && !isRunning)
{
animator.SetBool(IsRunning, true);
}
else if ((!isMovementPressed || !isRunPressed) && isRunning)
{
animator.SetBool(IsRunning, false);
}
}
private void Update()
{
UpdateMovement();
HandleAnimation();
HandleRotation();
if (isRunPressed)
{
characterController.Move(currentRunMovement * (speed * Time.deltaTime));
}
else
{
characterController.Move(currentMovement * (speed * Time.deltaTime));
}
HandleGravity();
HandleJump();
}
private void OnEnable()
{
playerInput.Player.Enable();
}
private void OnDisable()
{
playerInput.Player.Disable();
}
}

На этой гифке я демонстрирую проблему: игрок должен оставаться на земле, используя силу тяжести, и даже когда я отрываюсь от земли, игрок не падает. В моменты, когда я стою на месте, я несколько раз нажимаю пробел, пытаясь подпрыгнуть, как вы видите, ничего не происходит. (единственная часть, которую я отклонился от самого урока, это то, что я реализовал движение с помощью камеры)
Надеюсь, кто-нибудь сможет найти мою проблему
Вот руководство для справки: https://www .youtube.com/watch?v=h2r3_KjChf4&list=PLwyUzJb_FNeQrIxCEjj5AMPwawsw5beAy&index=4
Подробнее здесь: https://stackoverflow.com/questions/793 ... k-properly
Мобильная версия