Unity中移动平台的奇怪输出

5
首先,很抱歉如果这篇文章写得不太好,我已经花了几个小时来调试它,感到非常有压力。我正在尝试在Unity中制作一个可以在路标之间移动的运动平台,但我不想在世界中放置大量的游戏对象占用宝贵的处理能力,因此我正在尝试使用一些可以通过编辑器添加到脚本中的东西。
唯一的问题是它似乎以难以置信的速度进行这项工作: enter image description here 黑色=相机视图,蓝色=基于路点移动的平台和它应该去的地方,红色=当前正在做什么。
我花了几个小时来找到解决方法,但我不知道为什么它会这样做。
我的平台脚本:
public Vector3[] localWaypoints;
    Vector3[] globalWaypoints;

    public float speed;
    public bool cyclic;
    public float waitTime;
    [Range(0, 2)]
    public float easeAmount;

    int fromWaypointIndex;
    float percentBetweenWaypoints;
    float nextMoveTime;

    void Start()
    {

        globalWaypoints = new Vector3[localWaypoints.Length];
        for (int i = 0; i < localWaypoints.Length; i++)
        {
            globalWaypoints[i] = localWaypoints[i] + transform.position;
        }
    }

    void Update()
    {


        Vector3 velocity = CalculatePlatformMovement();
        transform.Translate(velocity);
    }

    float Ease(float x)
    {
        float a = easeAmount + 1;
        return Mathf.Pow(x, a) / (Mathf.Pow(x, a) + Mathf.Pow(1 - x, a));
    }

    Vector3 CalculatePlatformMovement()
    {

        if (Time.time < nextMoveTime)
        {
            return Vector3.zero;
        }

        fromWaypointIndex %= globalWaypoints.Length;
        int toWaypointIndex = (fromWaypointIndex + 1) % globalWaypoints.Length;
        float distanceBetweenWaypoints = Vector3.Distance(globalWaypoints[fromWaypointIndex], globalWaypoints[toWaypointIndex]);
        percentBetweenWaypoints += Time.deltaTime * speed / distanceBetweenWaypoints;
        percentBetweenWaypoints = Mathf.Clamp01(percentBetweenWaypoints);
        float easedPercentBetweenWaypoints = Ease(percentBetweenWaypoints);

        Vector3 newPos = Vector3.Lerp(globalWaypoints[fromWaypointIndex], globalWaypoints[toWaypointIndex], easedPercentBetweenWaypoints);

        if (percentBetweenWaypoints >= 1)
        {
            percentBetweenWaypoints = 0;
            fromWaypointIndex++;

            if (!cyclic)
            {
                if (fromWaypointIndex >= globalWaypoints.Length - 1)
                {
                    fromWaypointIndex = 0;
                    System.Array.Reverse(globalWaypoints);
                }
            }
            nextMoveTime = Time.time + waitTime;
        }

        return newPos - transform.position;
    }


    struct PassengerMovement
    {
        public Transform transform;
        public Vector3 velocity;
        public bool standingOnPlatform;
        public bool moveBeforePlatform;

        public PassengerMovement(Transform _transform, Vector3 _velocity, bool _standingOnPlatform, bool _moveBeforePlatform)
        {
            transform = _transform;
            velocity = _velocity;
            standingOnPlatform = _standingOnPlatform;
            moveBeforePlatform = _moveBeforePlatform;
        }
    }

    void OnDrawGizmos()
    {
        if (localWaypoints != null)
        {
            Gizmos.color = Color.red;
            float size = .3f;

            for (int i = 0; i < localWaypoints.Length; i++)
            {
                Vector3 globalWaypointPos = (Application.isPlaying) ? globalWaypoints[i] : localWaypoints[i] + transform.position;
                Gizmos.DrawLine(globalWaypointPos - Vector3.up * size, globalWaypointPos + Vector3.up * size);
                Gizmos.DrawLine(globalWaypointPos - Vector3.left * size, globalWaypointPos + Vector3.left * size);
            }
        }
    }
更新: 经过进一步测试,我发现如果我本地航点数组中的第一个对象设置为0,0,0,而我的第二个对象设置为1,0,0,则平台将向右螺旋,确保在螺旋时击中航点,然后像上图一样螺旋到无处。但是,如果我将第一个对象设置为0,0,0,将第二个对象设置为-1,0,0,则对象将像以前一样操作,但是将像此图所示向左螺旋。(第二张图片也已更新,显示了平台如何确保在螺旋到无处之前击中两个航点)。

enter image description here

我还注意到,如果我将两个航点都设置为0,0,0,则平台保持静止,这两件事证明它与处理航点的方式有关,而不是其他脚本或父对象的干扰。


2
你的代码似乎可以处理简单的数据集。你使用的航点数据集是什么? - Topher
2
有没有其他脚本在运行,可能会影响您平台的位置? - Topher
1
我想知道你的平台是否存储在一个空的游戏对象中,而在将平台设置为子对象之前没有重置其变换?如果是这种情况,您可能需要从空对象中删除所有子对象并重置变换,然后再将子对象放回去。在运行时,子对象会采用父对象的变换位置,并导致发生诸如此类的奇怪事情。 - AntonioTorro
@Topher 我没有任何其他脚本与它相关,否则会影响它。我假设你说的数据集是指我的航点所在的位置,我现在有两个,element0位于0,0,0,而element1位于1,0,0。 - Jhon Piper
@AntonioTorro 平台不是任何东西的子级,所以我不知道还有什么其他因素会影响它。 - Jhon Piper
显示剩余3条评论
1个回答

3

使用更新后的数字([0,0,0],[1,0,0])在我的测试应用程序中是有效的。但是,如果我在对象的Y轴上放置旋转,则会看到您所看到的行为。在Update中,如果您更改:

transform.Translate(velocity);

to

transform.Translate(velocity, Space.World); 

你应该能看到你期望的行为。请注意,“transform.Translate(velocity)”和“transform.Translate(velocity, Space.Self)”是相同的。你的平移正在被旋转。
如果你好奇,可以查看以下链接了解有关如何应用变换中的值的更多信息: https://gamedev.stackexchange.com/questions/138358/what-is-the-transformation-order-when-using-the-transform-class

那个运行得非常完美!非常感谢你,也感谢你提供了学习如何影响它的资源! - Jhon Piper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接