0

我正在开发一个 3 车道 3d 无尽的跑步游戏,我遇到了这个问题。

在堆栈溢出的一些帮助下,我设法在 3 条车道中切换我的角色,几秒钟后,我的角色慢慢地离开车道,而不是在每条车道上跑一条直线。切换角色后离开车道。这真的很烦人。我如何解决它?

我开始注意到角色的x轴,点值一点一点增加。例如,如果它是正确的车道,它应该是 1.0000,但在切换后它会逐渐增加 1.0045、1.0345、1.09585 等等,反之亦然。有时它也会破坏 3 车道移动,角色试图一直向右或向左移动而不停止,所以我不得不停止播放模式。

帮助将不胜感激。

这是我的脚本。

//Variables for Lane switching 
    private bool isChangingLane = false;
    private Vector3 locationAfterChanginLane = Vector3.zero;
    private Vector3 sideWayMovementDistance = Vector3.right * 2f; // This might be the case that triggers abnormal movements
    private float sideWaySpeed = 6f;

    public enum Lane
    {
        Left,
        Right,
        Center
    }

    public enum MoveDirection
    {
        Left,
        Right,
        None
    }

    Lane currentLane = Lane.Center;

     void Update()
    {
        currentBaseState = anim.GetCurrentAnimatorStateInfo(0);

        if (controller.isGrounded)
        {
            verticalVelocity = -0.5f;
            if (currentBaseState.fullPathHash == locoState)
            {
                if (Input.GetButtonDown("Jump"))
                {
                    verticalVelocity = 18f;

                    anim.SetBool("Jump", true);
                }
                else if (Input.GetKeyDown(KeyCode.S))
                {
                    anim.SetBool("Slide", true);
                }

            }

            MoveLeftRight(); // This is the method to move right and left.

            if (isChangingLane)
            {
                if (Math.Abs(transform.position.x - locationAfterChanginLane.x) < 0.1f)
                {
                    isChangingLane = false;
                    moveVector.x = 0;
                }
            }



        }
    }

    private void MoveLeftRight()
    {

        MoveDirection requestedMoveDirection = MoveDirection.None;
        if (Input.GetKeyDown(KeyCode.A) && !isChangingLane)
        {
            requestedMoveDirection = MoveDirection.Left;
            isChangingLane = true;
        }
        else if (Input.GetKeyDown(KeyCode.D) && !isChangingLane)
        {
            requestedMoveDirection = MoveDirection.Right;
            isChangingLane = true;
        }

        switch (requestedMoveDirection)
        {
            case MoveDirection.Right:
                if (currentLane == Lane.Right)
                {
                    Debug.Log("Right Lane");
                    break; //Do nothing when in right lane.

                }
                else if (currentLane == Lane.Center)
                {
                    locationAfterChanginLane = transform.position + sideWayMovementDistance;
                    moveVector.x = +sideWaySpeed;

                    currentLane = Lane.Right;
                    Debug.Log("Center --> Right");
                }
                else if (currentLane == Lane.Left)
                {
                    locationAfterChanginLane = transform.position + sideWayMovementDistance;
                    moveVector.x = +sideWaySpeed;

                    currentLane = Lane.Center;
                    Debug.Log("Left --> Center");
                }
                break;
            case MoveDirection.Left:
                if (currentLane == Lane.Left)
                {
                    Debug.Log("Left Lane");
                    break; //Do nothing when in left lane.
                }
                else if (currentLane == Lane.Center)
                {
                    locationAfterChanginLane = transform.position - sideWayMovementDistance;
                    moveVector.x = -sideWaySpeed;

                    currentLane = Lane.Left;

                    Debug.Log("Center --> Left");
                }
                else if (currentLane == Lane.Right)
                {
                    locationAfterChanginLane = transform.position - sideWayMovementDistance;
                    moveVector.x = -sideWaySpeed;

                    currentLane = Lane.Center;

                    Debug.Log("Right --> Center");
                }
                break;
        }
    }
4

2 回答 2

2

相当简单,在检查角色当前位置是否接近最终位置的代码部分,也设置最终位置。

if (Math.Abs(transform.position.x - locationAfterChanginLane.x) < 0.1f)
{
    isChangingLane = false;
    moveVector.x = 0;
    transform.position = locationAfterChanginLane; //Add this line
}

发生这种情况的原因本质上是该Update功能的工作方式。Monobehaviour 的更新不是在固定的时间步长上调用的(我们称之为Time.deltaTime)。因此,在大多数情况下,您角色的位置会超过/低于最终值。

于 2016-08-14T18:22:59.783 回答
0

所以我终于找到了我对这个问题的答案,所以就到这里了。最简单的方法是使用 Clamp 来解决问题。这是我实施的。

Update 函数中的 Clamp 方法。

public static float Clamp(float val, float min, float max)
    {
        return (val < min) ? min : (val > max) ? max : val;
    }

在我的MoveLeftRight()想法中,

switch (requestedMoveDirection)
        {
            case MoveDirection.Right:
                if (currentLane == Lane.Right)
                {
                    break; //Do nothing when in right lane.                    
                }
                else if (currentLane == Lane.Center)
                {
                    locationAfterChangingLane = transform.position + sideWayMovementDistance;
                    moveVector.x = +sideWaySpeed;

                    locationAfterChangingLane.x = Clamp(locationAfterChangingLane.x, RightLaneMin, RightLaneMax);
                    currentLane = Lane.Right;
                }
                else if (currentLane == Lane.Left)
                {
                    locationAfterChangingLane = transform.position + sideWayMovementDistance;
                    moveVector.x = +sideWaySpeed;

                    locationAfterChangingLane.x = Clamp(locationAfterChangingLane.x, centerLaneMin, centerLaneMax);
                    currentLane = Lane.Center;
                }
                break;

            case MoveDirection.Left:
                if (currentLane == Lane.Left)
                {
                    break; //Do nothing when in left lane.
                }
                else if (currentLane == Lane.Center)
                {
                    locationAfterChangingLane = transform.position - sideWayMovementDistance;
                    moveVector.x = -sideWaySpeed;

                    locationAfterChangingLane.x = Clamp(locationAfterChangingLane.x, leftLaneMin, leftLaneMax);
                    currentLane = Lane.Left;
                }
                else if (currentLane == Lane.Right)
                {
                    locationAfterChangingLane = transform.position - sideWayMovementDistance;
                    moveVector.x = -sideWaySpeed;

                    locationAfterChangingLane.x = Clamp(locationAfterChangingLane.x, centerLaneMin, centerLaneMax);
                    currentLane = Lane.Center;
                }
                break;
        }

你去吧。希望能帮助到你。感谢大家的帮助。快乐编码。

于 2016-08-19T18:21:27.410 回答