Unity 3D 运动问题

问题描述 投票:0回答:1

所以我正在尝试创建一个与状态机和新输入系统统一的 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);
    }
c# unity-game-engine unityscript
1个回答
0
投票

首先,启用

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;
}
© www.soinside.com 2019 - 2024. All rights reserved.