[英]Character doesn't jump sometimes - Unity
我是 Unity 的新手,我正在為我的角色使用以下CharacterController 。 一切都運行良好,除了有時角色會跳躍,有時當我按下空格鍵時不會。 我使用 Raycast 使用 Debog.Log 檢查我的角色是否接地,結果為 True。 那么是什么阻止了我的角色在我擊鍵時跳躍?
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(CharacterController))]
public class RPGMovement : MonoBehaviour
{
public float ForwardSpeed = 8f;
public float BackwardSpeed = 4f;
public float StrafeSpeed = 5f;
public float RotateSpeed = 110f;
CharacterController m_CharacterController;
Vector3 m_LastPosition;
Animator m_Animator;
PhotonView m_PhotonView;
PhotonTransformView m_TransformView;
float m_AnimatorSpeed;
Vector3 m_CurrentMovement;
float m_CurrentTurnSpeed;
Vector3 playerVelocity;
private bool groundedPlayer;
private float jumpHeight = 0.9f;
private float gravityValue = -20.81f;
void Start()
{
m_CharacterController = GetComponent<CharacterController>();
m_Animator = GetComponent<Animator>();
m_PhotonView = GetComponent<PhotonView>();
m_TransformView = GetComponent<PhotonTransformView>();
}
void Update()
{
if (m_PhotonView.isMine == true)
{
ResetSpeedValues();
UpdateRotateMovement();
UpdateForwardMovement();
UpdateBackwardMovement();
UpdateStrafeMovement();
MoveCharacterController();
UpdateJump();
ApplySynchronizedValues();
}
UpdateAnimation();
}
void UpdateAnimation()
{
Vector3 movementVector = transform.position - m_LastPosition;
float speed = Vector3.Dot(movementVector.normalized, transform.forward);
float direction = Vector3.Dot(movementVector.normalized, transform.right);
if (Mathf.Abs(speed) < 0.2f)
{
speed = 0f;
}
if (speed > 0.6f)
{
speed = 1f;
direction = 0f;
}
if (speed >= 0f)
{
if (Mathf.Abs(direction) > 0.7f)
{
speed = 1f;
}
}
m_AnimatorSpeed = Mathf.MoveTowards(m_AnimatorSpeed, speed, Time.deltaTime * 5f);
m_Animator.SetFloat("Speed", m_AnimatorSpeed);
m_Animator.SetFloat("Direction", direction);
m_LastPosition = transform.position;
}
void ResetSpeedValues()
{
m_CurrentMovement = Vector3.zero;
m_CurrentTurnSpeed = 0;
}
void ApplySynchronizedValues()
{
m_TransformView.SetSynchronizedValues(m_CurrentMovement, m_CurrentTurnSpeed);
}
void MoveCharacterController()
{
m_CharacterController.Move(m_CurrentMovement * Time.deltaTime);
}
void UpdateForwardMovement()
{
if (Input.GetKey(KeyCode.W) || Input.GetAxisRaw("Vertical") > 0.1f)
{
m_CurrentMovement = transform.forward * ForwardSpeed;
}
}
void UpdateBackwardMovement()
{
if (Input.GetKey(KeyCode.S) || Input.GetAxisRaw("Vertical") < -0.1f)
{
m_CurrentMovement = -transform.forward * BackwardSpeed;
}
}
void UpdateStrafeMovement()
{
if (Input.GetKey(KeyCode.Q) == true)
{
m_CurrentMovement = -transform.right * StrafeSpeed;
}
if (Input.GetKey(KeyCode.E) == true)
{
m_CurrentMovement = transform.right * StrafeSpeed;
}
}
void UpdateRotateMovement()
{
if (Input.GetKey(KeyCode.A) || Input.GetAxisRaw("Horizontal") < -0.1f)
{
m_CurrentTurnSpeed = -RotateSpeed;
transform.Rotate(0.0f, -RotateSpeed * Time.deltaTime, 0.0f);
}
if (Input.GetKey(KeyCode.D) || Input.GetAxisRaw("Horizontal") > 0.1f)
{
m_CurrentTurnSpeed = RotateSpeed;
transform.Rotate(0.0f, RotateSpeed * Time.deltaTime, 0.0f);
}
}
void UpdateJump()
{
groundedPlayer = m_CharacterController.isGrounded;
if (groundedPlayer && playerVelocity.y < 0)
{
playerVelocity.y = 0f;
}
if (Input.GetButtonDown("Jump") && groundedPlayer)
{
playerVelocity.y += Mathf.Sqrt(jumpHeight * -3.0f * gravityValue);
m_Animator.SetTrigger("Jump");
print("Jumping Now");
}
playerVelocity.y += gravityValue * Time.deltaTime;
m_CharacterController.Move(playerVelocity * Time.deltaTime);
}
}
最好的猜測是“m_PhotonView.isMine”在您缺少輸入的幀上沒有返回true。 它只檢查該幀的跳轉輸入,因此如果您按下的最后一幀但未檢查跳轉,則該輸入將永遠丟失。 首先測試這個。 將更新代碼更改為:
void Update()
{
if (Input.GetButtonDown("Jump")) { Debug.Log("Jump was pressed at {Time.time}"); }
if (m_PhotonView.isMine == true)
{
if (Input.GetButtonDown("Jump")) { Debug.Log("Attempting Jump at {Time.time}"); }
ResetSpeedValues();
UpdateRotateMovement();
UpdateForwardMovement();
UpdateBackwardMovement();
UpdateStrafeMovement();
MoveCharacterController();
UpdateJump();
ApplySynchronizedValues();
}
UpdateAnimation();
}
然后玩游戲,跳一堆。 無論如何,每次單擊空格鍵時都會出現第一個調試日志行。 只有在該幀計算物理時才會出現第二條調試線。 兩者都附有時間。 繼續跳躍,直到跳躍不起作用。 如果那個跳轉只產生第一個調試日志而不是第二個,那么我是對的,那是你的問題。
如果是這樣,那么它很容易解決。 添加一個名為“jumpInput”的新布爾變量。 每當您檢查是否按下了跳轉時,請檢查“jumpInput”是否為真。 然后,將更新更改為:
void Update()
{
if (Input.GetButtonDown("Jump")) { jumpInput = true; }
if (m_PhotonView.isMine == true)
{
ResetSpeedValues();
UpdateRotateMovement();
UpdateForwardMovement();
UpdateBackwardMovement();
UpdateStrafeMovement();
MoveCharacterController();
UpdateJump();
ApplySynchronizedValues();
jumpInput = false;
}
UpdateAnimation();
}
這樣,如果你按下跳轉,它會被設置為 true...但它只會在物理完成后設置為 false。 因此,如果您在第 20 幀上按下 jump 並且在第 25 幀之前以某種方式不計算物理,它仍然會知道您在某個點按下了 jump 並因此執行它。 如果您正在使用網絡,您可能還需要另一個變量,即按下的跳幀。 這樣您就可以計算出自輸入以來已經過去了多少幀,並在必要時補償跳躍中錯過的時間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.