嗨,我处于游戏开发的初期阶段,在使玩家动作正常运行方面遇到一些问题,所以我想我可以试试运气,看看这里是否有人可以帮助我
我遇到的问题是,我已经制作了一个状态机来跟踪我的状态和在它们之间进行切换的规则,这些状态和规则似乎在一开始就起作用了,但是我似乎无法弄清楚从行走状态切换到空闲状态的代码,跌落至空闲状态,跌落至行走状态。如果我尝试添加代码以在玩家不移动时切换到空闲状态,那么我将完全无法行走,因为一旦我尝试行走,状态就会立即回到空闲状态,如果我一接触地面,我就会跳起来,玩家只是站着不动,我必须释放步行按钮,然后再次按一下以恢复步行。
下面是我正在处理的代码。
StateMachine.cs
public interface IState
{
void Enter();
void Execute();
void ExecutePhysics();
void Exit();
}
public interface StateManaged
{
void RequestState(IState requestedState);
}
public class StateMachine
{
public IState currentState;
public void ChangeState(IState newState)
{
if (currentState != null)
currentState.Exit();
currentState = newState;
currentState.Enter();
}
public void Update()
{
if (currentState != null)
currentState.Execute();
}
public void FixedUpdate()
{
if (currentState != null)
currentState.ExecutePhysics();
}
}
PlayerController.cs
public class PlayerController : MonoBehaviour, StateManaged
{
StateMachine stateMachine = new StateMachine();
public float speed = 5.0f;
public float jump = 20.0f;
bool isGrounded = true;
private Rigidbody playerRigidbody;
private void Awake()
{
playerRigidbody = GetComponent<Rigidbody>();
}
void Start()
{
RequestState(new IdleState(this));
}
void Update()
{
Debug.Log(stateMachine.currentState);
CaptureInput();
stateMachine.Update();
}
void FixedUpdate()
{
UpdateStateFromPhysics();
stateMachine.FixedUpdate();
}
private void CaptureInput()
{
if (Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.D))
RequestState(new WalkState(this));
if (Input.GetButtonDown("Jump"))
RequestState(new JumpState(this));
}
private void UpdateStateFromPhysics()
{
if (playerRigidbody.velocity.y < -.01 && !isGrounded)
RequestState(new FallState(this));
}
#region
// Manage state transition rules
public void RequestState(IState requestedState)
{
Debug.Log(requestedState.ToString());
// Idle
if (requestedState is IdleState)
{
if (stateMachine.currentState is null || stateMachine.currentState is WalkState || stateMachine.currentState is FallState)
stateMachine.ChangeState(requestedState);
}
// Walk
if (requestedState is WalkState)
{
if (stateMachine.currentState is IdleState || stateMachine.currentState is FallState)
stateMachine.ChangeState(requestedState);
}
// Jump
if (requestedState is JumpState)
{
if (stateMachine.currentState is IdleState || stateMachine.currentState is WalkState)
stateMachine.ChangeState(requestedState);
}
// Fall
if (requestedState is FallState)
if (stateMachine.currentState is JumpState || stateMachine.currentState is WalkState)
stateMachine.ChangeState(requestedState);
}
public class IdleState : IState
{
PlayerController player;
public IdleState(PlayerController player)
{
this.player = player;
}
public void Enter()
{
}
public void Execute()
{
}
public void ExecutePhysics()
{
}
public void Exit()
{
}
}
public class WalkState : IState
{
PlayerController player;
public WalkState(PlayerController player)
{
this.player = player;
}
public void Enter()
{
}
public void Execute()
{
Vector3 movement = new Vector3(Input.GetAxis("Horizontal") * player.speed, 0f, Input.GetAxis("Vertical") * player.speed);
player.playerRigidbody.transform.position += movement * Time.deltaTime;
}
public void ExecutePhysics()
{
}
public void Exit()
{
}
}
public class JumpState : IState
{
PlayerController player;
public JumpState(PlayerController player)
{
this.player = player;
}
public void Enter()
{
Vector3 jumping = new Vector3(0, player.jump, 0);
player.playerRigidbody.AddForce(jumping, ForceMode.Impulse);
}
public void Execute()
{
}
public void ExecutePhysics()
{
}
public void Exit()
{
}
}
public class FallState : IState
{
PlayerController player;
public FallState(PlayerController player)
{
this.player = player;
}
public void Enter()
{
}
public void Execute()
{
}
public void ExecutePhysics()
{
}
public void Exit()
{
}
}
#endregion
}