Осваиваю новую систему. Сейчас делаю приседание. При нажатии на клавишу персонаж садится, а при отпускании встает, но если над ним находится потолок (об этом условии в методе Stand), то он не встает. Вроде бы все нормально, но если выйти из под потолка, то персонаж все равно сидит. Метод Stand вызывается тогда, когда отпускается клавиша и поэтому оно проверяется только 1 раз. Есть ли какое-то +- нормальное решение проблемы? Боюсь, что мой способ будет не очень, да и не факт, что сработает)
Вот весь код (нужные методы в самом низу):
using UnityEngine;
public class Player : MonoBehaviour
{
#region ANIMATION
private const string MOVE_X = "MoveX";
private const string SQUAT = "Squat";
#endregion
[SerializeField] private float _moveSpeed;
[SerializeField] private float _crouchSpeed;
[SerializeField] private float _jumpForce;
[SerializeField] private float _smoothTime;
[SerializeField] private Transform _topCheck;
[SerializeField] private float _topCheckRadius;
[SerializeField] private LayerMask _roof;
[SerializeField] private Collider2D _poseStand;
[SerializeField] private Collider2D _poseSquat;
private Vector2 _moveDirection;
private Vector2 nullVector = Vector2.zero;
private Animator _animator;
private PlayerInput _playerInput;
private Rigidbody2D _rigidbody;
private bool _faceRight = true;
private void Awake()
{
_playerInput = new PlayerInput();
_playerInput.Player.Move.performed += context => Move();
_playerInput.Player.Jump.performed += context => Jump();
_playerInput.Player.Crouch.performed += context => Crouch();
_playerInput.Player.Crouch.canceled += context => Stand();
_animator = GetComponent<Animator>();
_rigidbody = GetComponent<Rigidbody2D>();
_topCheckRadius = _topCheck.GetComponent<CircleCollider2D>().radius;
}
private void Update()
{
_moveDirection = _playerInput.Player.Move.ReadValue<Vector2>();
Move();
}
private void OnEnable() => _playerInput.Enable();
private void OnDisable() => _playerInput.Disable();
private void Move()
{
float targetVelocityX = DetermineTargetVelocityX();
Vector2 targetVelocity = new Vector2(targetVelocityX, _rigidbody.velocity.y);
_rigidbody.velocity = Vector2.SmoothDamp(_rigidbody.velocity, targetVelocity, ref nullVector, _smoothTime);
_animator.SetFloat(MOVE_X, Mathf.Abs(_moveDirection.x));
bool isWalking = _moveDirection != Vector2.zero;
if (isWalking && Mathf.Sign(_moveDirection.x) != Mathf.Sign(transform.localScale.x))
Flip();
}
private float DetermineTargetVelocityX()
{
float targetVelocityX = _moveDirection.x * _moveSpeed;
if (_animator.GetBool(SQUAT))
targetVelocityX = _moveDirection.x * _crouchSpeed;
return targetVelocityX;
}
private void Flip()
{
_faceRight = !_faceRight;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
private void Jump()
{
_rigidbody.velocity = new Vector2(_rigidbody.velocity.x, _jumpForce);
}
private void Crouch()
{
_animator.SetBool(SQUAT, true);
_poseStand.enabled = false;
_poseSquat.enabled = true;
}
private void Stand()
{
if (!Physics2D.OverlapCircle(_topCheck.position, _topCheckRadius, _roof))
{
_animator.SetBool(SQUAT, false);
_poseStand.enabled = true;
_poseSquat.enabled = false;
}
}
}