首先,我想為我的英語道歉,因為我來自波蘭,我還在學習。我是一名初學者 C#/Unity 程式員,我有一個非常愚蠢/菜鳥問題/問題,玩家在混合空間時會跳兩次。當幀率較低時。30,這個問題幾乎每次都會出現,并且當幀率是 ex。144 - 幾乎沒有。我做了一些研究并嘗試了不同的方法。首先,我檢查了我的所有輸入是否都在 Update 而不是 FixedUpdate 中。那根本不是問題。然后我嘗試在 Update 中將 Input.GetKey 替換為 Input.GetKeyDown 和 GetKeyUp,以確保我的布爾 _spacePressed 被選中。那也不是解決方案。我嘗試的第三件事是使用 Raycasting 檢查播放器是否接地。有了這個,我還檢查了當我跳的時候,雷是否' t 被檢查兩次。為了清楚起見,我目前正在嘗試制作 2.5D 平臺游戲。所以總而言之,我在問什么可能是主要問題(可能是輸入),玩家在混合空間時在單幀中跳躍兩次甚至三次。這也是我的原型代碼。我使用列舉來制作一個簡單的狀態“機器”。如果您對我和我的代碼有任何建議,除了我的問題之外,我很想聽聽他們的意見。先感謝您!如果您對我和我的代碼有任何建議,除了我的問題之外,我很想聽聽他們的意見。先感謝您!如果您對我和我的代碼有任何建議,除了我的問題之外,我很想聽聽他們的意見。先感謝您!
using UnityEngine;
public class Movement : MonoBehaviour
{
[Header("Start Properties")]
[SerializeField] private Transform _playerTransform;
[SerializeField] private Rigidbody _playerRigidbody;
private enum MovementStates { reset, idle, walking, walkingInAir, sprinting, jumping };
private MovementStates _currentState;
[Header("Player Height Adjustables")]
[SerializeField] CapsuleCollider _playerCollider;
[SerializeField] private float _reducedHeight;
private float _originalHeight;
[Header("Player Rotation Adjustables")]
[SerializeField] private float _rotationSpeed;
Quaternion _from;
Quaternion _to;
[Header("Input Properties")]
private float _xAxis;
private bool _rightLook, _leftLook;
private bool _idle, _walking, _walkingInAir, _sprinting, _reset;
private bool _leftShiftPressed;
private bool _spacePressed;
[Header("Player Movement Adjustables")]
[SerializeField] private float _walkingSpeedMultiplier;
[SerializeField] private float _maximumWalkingSpeed;
[SerializeField] private float _walkingInAirSpeedMultiplier;
[SerializeField] private float _maximumWalkingInAirSpeed;
[SerializeField] private float _sprintingSpeedMultiplier;
[SerializeField] private float _maximumSprintingSpeed;
[SerializeField] private float _deaccelerationMultiplier;
[Header("Smooth Damp Adjustables")]
[SerializeField] private float _smoothTime;
private Vector3 _currentVelocity;
private Vector3 _smoothAxis;
[Header("Player Jump Adjustables")]
[SerializeField] private float _jumpMultiplier;
private bool _jumping;
[Header("Ground Check Adjustables")]
[SerializeField] private LayerMask _groundCheck_Layer;
[SerializeField] private float _distanceGroundCheck;
private Ray _groundCheck_Ray;
private RaycastHit _groundCheck_HitInfo;
private bool _grounded;
private void Awake()
{
_originalHeight = _playerCollider.height;
}
// input and ground checks
private void Update()
{
Process_Input();
Process_Rotation();
GroundRay_Check();
}
private void Process_Input()
{
_xAxis = Input.GetAxisRaw("Horizontal");
_rightLook = (_xAxis > 0) ? _rightLook = true : _rightLook = false;
_leftLook = (_xAxis < 0) ? _leftLook = true : _leftLook = false;
if (Input.GetKeyDown(KeyCode.LeftShift)) _leftShiftPressed = true;
if (Input.GetKeyUp(KeyCode.LeftShift)) _leftShiftPressed = false;
if (Input.GetButtonDown("Jump")) _spacePressed = true;
if (Input.GetButtonUp("Jump")) _spacePressed = false;
_idle = (_xAxis == 0 && _grounded) ? _idle = true : _idle = false;
_walking = (_xAxis != 0 && !_leftShiftPressed && _grounded) ? _walking = true : _walking = false;
_walkingInAir = (_xAxis != 0 && !_grounded) ? _walkingInAir = true : _walkingInAir = false;
_sprinting = (_xAxis != 0 && _leftShiftPressed && _grounded) ? _sprinting = true : _sprinting = false;
_jumping = (_spacePressed && _grounded) ? _jumping = true : _jumping = false;
_reset = (!_idle && !_walking && !_walkingInAir && !_sprinting && !_jumping) ? _reset = true : _reset = false;
if (Input.GetKeyDown(KeyCode.Alpha1)) Application.targetFrameRate = 30;
if (Input.GetKeyDown(KeyCode.Alpha2)) Application.targetFrameRate = 60;
if (Input.GetKeyDown(KeyCode.Alpha3)) Application.targetFrameRate = 120;
if (Input.GetKeyDown(KeyCode.Alpha4)) Application.targetFrameRate = 144;
}
private void Process_Rotation()
{
if (_rightLook)
{
_from = _playerTransform.rotation;
_to = Quaternion.Euler(0f, 0f, 0f);
_playerTransform.rotation = Quaternion.Lerp(_from, _to, _rotationSpeed * Time.deltaTime);
}
else if (_leftLook)
{
_from = _playerTransform.rotation;
_to = Quaternion.Euler(0f, 180f, 0f);
_playerTransform.rotation = Quaternion.Lerp(_from, _to, _rotationSpeed * Time.deltaTime);
}
}
private void GroundRay_Check()
{
_groundCheck_Ray.origin = _playerTransform.position;
_groundCheck_Ray.direction = Vector2.down;
Debug.DrawRay(_playerTransform.position, Vector2.down * _distanceGroundCheck, Color.green);
_grounded = Physics.Raycast(_groundCheck_Ray, out _groundCheck_HitInfo, _distanceGroundCheck, _groundCheck_Layer, QueryTriggerInteraction.Ignore);
}
// movement by states
private void FixedUpdate()
{
Process_States();
}
private void Process_States()
{
if (_idle) _currentState = MovementStates.idle;
if (_walking) _currentState = MovementStates.walking;
if (_walkingInAir) _currentState = MovementStates.walkingInAir;
if (_sprinting) _currentState = MovementStates.sprinting;
if (_jumping) _currentState = MovementStates.jumping;
if (_reset) _currentState = MovementStates.reset;
switch (_currentState)
{
case MovementStates.idle:
Process_Idle();
break;
case MovementStates.walking:
Process_Walking();
break;
case MovementStates.walkingInAir:
Process_WalkingInAir();
break;
case MovementStates.sprinting:
Process_Sprinting();
break;
case MovementStates.jumping:
Process_Jumping();
break;
case MovementStates.reset:
print("resetting");
return;
}
}
private void Process_Idle()
{
print("currently idle");
_playerCollider.height = _originalHeight;
Deaccelerate(_deaccelerationMultiplier);
}
private void Process_Walking()
{
print("currently walking");
Move(_walkingSpeedMultiplier, _maximumWalkingSpeed, ForceMode.Force);
}
private void Process_WalkingInAir()
{
print("currently walking in air");
Move(_walkingInAirSpeedMultiplier, _maximumWalkingInAirSpeed, ForceMode.Force);
}
private void Process_Sprinting()
{
print("currently sprinting");
Move(_sprintingSpeedMultiplier, _maximumSprintingSpeed, ForceMode.Force);
}
private void Process_Jumping()
{
print("currently jumping");
Jump(_jumpMultiplier, ForceMode.VelocityChange);
_spacePressed = false;
}
// movement functions
private void Move(float _speedMultiplier, float _maximumSpeed, ForceMode _forceMode)
{
CapMaximumSpeed(_maximumSpeed);
Vector2 _getAxisDirection = _xAxis * Vector2.right;
Vector2 _normalizeAxis = _getAxisDirection.normalized;
Vector2 _multiplyAxis = _normalizeAxis * _speedMultiplier * Time.deltaTime;
_smoothAxis = Vector3.SmoothDamp(_multiplyAxis, _smoothAxis, ref _currentVelocity, _smoothTime);
_playerRigidbody.AddForce(_smoothAxis, _forceMode);
}
private void CapMaximumSpeed(float _maximumSpeed)
{
float _cappedXVelocity = Mathf.Min(Mathf.Abs(_playerRigidbody.velocity.x), _maximumSpeed) * Mathf.Sign(_playerRigidbody.velocity.x);
float _cappedYVelocity = _playerRigidbody.velocity.y;
_playerRigidbody.velocity = new Vector3(_cappedXVelocity, _cappedYVelocity, 0);
}
private void Deaccelerate(float _deaccelerationMultiplier)
{
float _currentSpeed = _playerRigidbody.velocity.magnitude;
float _newSpeed = _currentSpeed - _deaccelerationMultiplier;
if (_newSpeed < 0) _newSpeed = 0;
_playerRigidbody.velocity = _playerRigidbody.velocity.normalized * _newSpeed;
}
private void Jump(float _jumpMultiplier, ForceMode _forceMode)
{
Vector2 _direction = Vector2.up;
Vector2 _multiplyDirection = _direction * _jumpMultiplier;
_playerRigidbody.AddForce(_multiplyDirection, _forceMode);
}
}
uj5u.com熱心網友回復:
請記住,這FixedUpdate()可能會在一個幀內發生幾次。檢查是否_spacePressed == true在您的Process_Jumping().
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/424490.html
