C# 为什么';我的对象不能停止在变换上移动。平移?

C# 为什么';我的对象不能停止在变换上移动。平移?,c#,unity3d,C#,Unity3d,我想让一个对象在每次变换时移动另一个对象。平移,但对象到达目的地时不会停止移动 我在脚本中尝试了几件事,但我不知道会出现什么问题。一件事是:我的代码中有几种方法,它们可以使一些东西在不同的段落中以不同的方式移动。因此,我编写了一个小方法,它在Input.GetKey()上执行特定的方法,以查看当我不执行其他方法时是否相同,此外,我还注释了Update中调用的所有内容以确保。其他任何移动方法都不应影响对象。因此,我将只发布在更新中对GetKey调用的受影响的方法 “TransportFirst”到

我想让一个对象在每次变换时移动另一个对象。平移,但对象到达目的地时不会停止移动

我在脚本中尝试了几件事,但我不知道会出现什么问题。一件事是:我的代码中有几种方法,它们可以使一些东西在不同的段落中以不同的方式移动。因此,我编写了一个小方法,它在Input.GetKey()上执行特定的方法,以查看当我不执行其他方法时是否相同,此外,我还注释了Update中调用的所有内容以确保。其他任何移动方法都不应影响对象。因此,我将只发布在更新中对GetKey调用的受影响的方法

“TransportFirst”到“TransportFirst”是传递给检查器的空游戏对象。我还检查了转置是否在运行时移动,但没有,每帧的位置都相同

private void ElevateCaptain()
{
    targetRigid.isKinematic = true;

    var transFirst = new Vector3(transPointFirst.localPosition.x, transPointFirst.localPosition.y, 0);
    var transSecond = new Vector3(transPointSecond.localPosition.x, transPointSecond.localPosition.y, 0);
    var transThird = new Vector3(transPointThird.localPosition.x, transPointThird.localPosition.y, 0);
    var transFourth = new Vector3(transPointFourth.localPosition.x, transPointFourth.localPosition.y, 0);

    target.transform.Translate(transFirst * Time.deltaTime, Space.World);

    if (target.transform.position == transFirst)
        target.transform.Translate(transSecond * Time.deltaTime, Space.World);

    else if (target.transform.position == transSecond)
        target.transform.Translate(transThird * Time.deltaTime, Space.World);

    else if (target.transform.position == transThird)
        target.transform.Translate(transFourth * Time.deltaTime, Space.World);

    else if (target.transform.position == transFourth)
    {
        targetRigid.isKinematic = false;
    }
}

所以,我希望我的目标移动到第一个翻译,如果达到了,移动到第二个翻译,依此类推。事实是:目标朝着正确的方向移动,但从不停止。不管代码是这样执行的,还是在第一次transform.Translate调用后我省略了所有内容。物体移动到第一个点,越来越远,越来越远。。。当我选择这些点中的另一点作为第一个翻译时也是如此。我希望有人能帮助我。

这里发生了很多事情

如果您的
transpintfirst
transpintsecond
等有任何父游戏对象,将它们的
localPosition
目标的
position
进行比较可能会出现意外行为。最好直接比较它们的
位置
字段。此外,如果其位置的Z分量已经是
0
,则不需要为其创建重复的
Vector3

Translate
要求方向向量乘以距离,但您给出的似乎是位置向量。您可能希望使用来计算每个帧的
目标的位置。您将需要一个变量来设置您希望移动的速度,理想情况下,它将是一个公共字段,以便您可以在inspector中设置它

而且,正如Eddge所说,在任何违背逻辑的情况下,你都要先做
翻译

然而,在统一中,
Vector3
=
=
操作符已经检查了近似相等性,所以您可以在这里查看

您还需要考虑当对象位于两个位置之间时在帧上发生的情况。如果您在每一帧上调用

elevateCaptaint
,而它应该在移动,那么您可以检查它的当前位置是否位于每一个连续的点对之间,或者有一些变量跟踪到目前为止它“接触”的点

在这里编写您想要做的事情的一种更简单的方法是,当您希望它开始移动时,只调用一次
ElevateCaptain
。下面是一个示例,说明了通过这些更改和使用协同路由,您的代码可能会是什么样子:

public float elevateSpeed;
private bool captainElevating;

Start() 
{
    // ...
    captainElevating = false; 
    // ...
}

private void ElevateCaptain()
{
    if (!captainElevating) 
    {
        captainElevating = true;
        StartCoroutine("ElevateCaptainCoroutine");
    }
}

private IEnumerator ElevateCaptainCoroutine() 
{
    targetRigid.isKinematic = true

    while (target.transform.position != transPointFirst.position)
    {
        target.transform.position = Vector3.MoveTowards(
                target.transform.position,   
                transPointFirst.position,
                elevateSpeed * Time.deltaTime);
        yield return null;
    }

    while (target.transform.position != transPointSecond.position)
    {
        target.transform.position = Vector3.MoveTowards(
                target.transform.position,   
                transPointSecond.position,
                elevateSpeed * Time.deltaTime);
        yield return null;
    }

    while (target.transform.position != transPointThird.position)
    {
        target.transform.position = Vector3.MoveTowards(
                target.transform.position,   
                transPointThird.position,
                elevateSpeed * Time.deltaTime);
        yield return null;
    }

    while (target.transform.position != transPointFourth.position)
    {
        target.transform.position = Vector3.MoveTowards(
                target.transform.position,   
                transPointFourth.position,
                elevateSpeed * Time.deltaTime);
        yield return null;
    }

    targetRigid.isKinematic = false;
    captainElevating = false;
}
如果您决定执行
Coroutine
路线,则当您希望目标开始移动时,应尝试只调用
ElevateCaptain
一次,尽管包含
captainElevating
变量应防止在已经发生时调用它


协同程序或其他方式,这方面的一个改进可能是使用
游戏对象的
列表
,并让协同程序循环在列表上依次向每个目标移动
目标
。这样,在inspector中,您可以将任意多个
transpint
游戏对象拖动到列表中,并非常轻松地进行更改。协同程序方法的重复结构非常适合这种循环。

这里有很多事情要做

如果您的
transpintfirst
transpintsecond
等有任何父游戏对象,将它们的
localPosition
目标的
position
进行比较可能会出现意外行为。最好直接比较它们的
位置
字段。此外,如果其位置的Z分量已经是
0
,则不需要为其创建重复的
Vector3

Translate
要求方向向量乘以距离,但您给出的似乎是位置向量。您可能希望使用来计算每个帧的
目标的位置。您将需要一个变量来设置您希望移动的速度,理想情况下,它将是一个公共字段,以便您可以在inspector中设置它

而且,正如Eddge所说,在任何违背逻辑的情况下,你都要先做
翻译

然而,在统一中,
Vector3
=
=
操作符已经检查了近似相等性,所以您可以在这里查看

您还需要考虑当对象位于两个位置之间时在帧上发生的情况。如果您在每一帧上调用

elevateCaptaint
,而它应该在移动,那么您可以检查它的当前位置是否位于每一个连续的点对之间,或者有一些变量跟踪到目前为止它“接触”的点

在这里编写您想要做的事情的一种更简单的方法是,当您希望它开始移动时,只调用一次
ElevateCaptain
。下面是一个示例,说明了通过这些更改和使用协同路由,您的代码可能会是什么样子:

public float elevateSpeed;
private bool captainElevating;

Start() 
{
    // ...
    captainElevating = false; 
    // ...
}

private void ElevateCaptain()
{
    if (!captainElevating) 
    {
        captainElevating = true;
        StartCoroutine("ElevateCaptainCoroutine");
    }
}

private IEnumerator ElevateCaptainCoroutine() 
{
    targetRigid.isKinematic = true

    while (target.transform.position != transPointFirst.position)
    {
        target.transform.position = Vector3.MoveTowards(
                target.transform.position,   
                transPointFirst.position,
                elevateSpeed * Time.deltaTime);
        yield return null;
    }

    while (target.transform.position != transPointSecond.position)
    {
        target.transform.position = Vector3.MoveTowards(
                target.transform.position,   
                transPointSecond.position,
                elevateSpeed * Time.deltaTime);
        yield return null;
    }

    while (target.transform.position != transPointThird.position)
    {
        target.transform.position = Vector3.MoveTowards(
                target.transform.position,   
                transPointThird.position,
                elevateSpeed * Time.deltaTime);
        yield return null;
    }

    while (target.transform.position != transPointFourth.position)
    {
        target.transform.position = Vector3.MoveTowards(
                target.transform.position,   
                transPointFourth.position,
                elevateSpeed * Time.deltaTime);
        yield return null;
    }

    targetRigid.isKinematic = false;
    captainElevating = false;
}
如果您决定走
协同路线
路线,当您希望目标开始移动时,您应该尝试只调用
提升机长
一次,尽管包含
提升机长
变量