所以我正在尝试创建一个与状态机和新输入系统统一的 3D 角色运动。我遇到了一个问题,玩家在扫射时移动速度更快,但上、下、左、右移动是相同的。我已经标准化了 Vector3 moveDir。我该如何解决这个问题?
视频链接:Unity 3D运动问题
PlayerStateMachine 脚本:
CharacterController playerControl;
PlayerInputSystm playerInput;
PlayerBaseState playerCurrState;
PlayerStateFactory playerCurrFactory;
float xDir;
float zDir;
public CharacterController PlayerControl { get { return playerControl; } }
public PlayerBaseState PlayerCurrState { get { return playerCurrState; } set { playerCurrState = value; } }
public float XDir { get { return xDir; } set { xDir = value; } }
public float ZDir { get { return zDir; } set { zDir = value; } }
private void Awake()
{
playerControl = GetComponent<CharacterController>();
playerInput = new PlayerInputSystm();
playerCurrFactory = new PlayerStateFactory(this);
playerCurrState = playerCurrFactory.Idle();
playerCurrState.EnterState();
playerInput.Player.Movement.performed += OnMove;
playerInput.Player.Movement.canceled += OnMove;
}
void Update()
{
playerCurrState.UpdateState();
}
void OnMove(InputAction.CallbackContext ctx_move)
{
xDir = ctx_move.ReadValue<Vector3>().x;
zDir = ctx_move.ReadValue<Vector3>().z;
}
private void OnEnable()
{
playerInput.Player.Movement.Enable();
}
private void OnDisable()
{
playerInput.Player.Movement.Disable();
}
PlayerIdleState 脚本:
public override void UpdateState()
{
CheckSwitchState();
}
public override void ExitState()
{
}
public override void CheckSwitchState()
{
if(ctx.XDir != 0 || ctx.ZDir != 0)
{
SwitchState(factory.Run());
}
}
PlayerRunState 脚本:
public override void UpdateState()
{
CheckSwitchState();
PlayerMove();
}
public override void ExitState()
{
}
public override void CheckSwitchState()
{
if(ctx.XDir == 0 || ctx.ZDir == 0)
{
SwitchState(factory.Idle());
}
}
void PlayerMove()
{
Vector3 moveDir = new Vector3(ctx.XDir, 0, ctx.ZDir).normalized;
ctx.PlayerControl.Move(moveDir * 3 * Time.deltaTime);
}
首先,启用
event listeners
后,您的 OnEnable
应该位于 OnDisable
和 Player actions
方法中。 OnEnable
方法应该是这样的
private void OnEnable()
{
playerInput.Player.Enable();
playerInput.Player.Movement.performed += OnMove;
playerInput.Player.Movement.canceled += OnMove;
}
还有
OnDisable
private void OnDisable()
{
playerInput.Player.Movement.performed -= OnMove;
playerInput.Player.Movement.canceled -= OnMove;
playerInput.Player.Disable();
}
其次,你的
OnMove
方法应该读取 Vector2
类型,而不是 Vector3
,因为据我所知,没有输入设备可以给你 Vector3
,所以你的 OnMove
看起来像这样
void OnMove(InputAction.CallbackContext ctx_move)
{
var inputValue = ctx_move.ReadValue<Vector2>();
xDir = inputValue.x;
zDir = inputValue.y;
}