我希望一个对象在每次变换中移动另一个对象。进行翻译,但是当它到达目的地时它不会停止移动。
我在脚本中尝试了几种方法,但是我不知道可能是什么问题。一件事是:我的代码中有几种方法,这些方法使某些事情在不同的段落中发生不同的移动。因此,我编写了一个小方法,该方法在Input.GetKey()上执行特定的方法,以查看是否在不执行其他任何方法时是否相同,此外,我还注释了Update中调用的所有内容以确保确定。没有其他移动方法可以影响对象。因此,我将只发布在Update中的GetKey上调用的受影响的方法。
“ transPointFirst”到“ transPointFourth”是在检查器中传递的空gameObject。我还检查了TransPoints是否在运行时移动,但是没有,每帧相同的位置。
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调用之后都忽略了所有内容,都没有关系。对象移动到该第一点,并越来越远...当我选择这些点中的另一个作为第一平移时,也是如此。我希望有人能帮助我。
答案 0 :(得分:0)
这里有很多事情。
如果您的transPointFirst
,transPointSecond
等具有任何父游戏对象,则将其localPosition
与position
的{{1}}进行比较可能会产生意外的行为。最好直接比较它们的target
字段。另外,如果其位置的Z分量已经为position
,则无需创建它们的重复0
。
Vector3
期望方向矢量乘以距离,但您给出的似乎是位置矢量。您可能想使用Vector3.MoveTowards
计算每帧Translate
的位置。您需要一个变量来设置您要移动的速度,理想情况下,它是一个公共区域,因此您可以在检查器中进行设置。
此外,正如Eddge所说,您在每种情况下都首先进行target
,这违反了您想要的逻辑。
但是,在Unity中,Translate
的{{1}}和Vector3
运算符已经检查了近似相等性,因此您可以在其中进行操作。
您还需要考虑当对象位于两个位置之间时在帧上会发生什么。如果在应该移动的每一帧上调用==
,则可以检查其当前位置是否位于每个连续的点对之间,或者可以使用一些变量来跟踪其“触摸过的点” “ 至今。
一种更简单的写方法是使用Coroutine
s,然后在您希望它开始移动时只调用一次!=
。以下是这些更改和使用协程的代码示例:
ElevateCaptain
如果您决定走ElevateCaptain
路线,则当目标要开始移动时,尽管其中包含{ {1}}变量应防止在它已经发生时被调用。
协程或其他方式,对此的一种改进可能是使用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
并使列表中的Coroutine循环依次将ElevateCaptain
移向每个。这样,在检查器中,您可以将任意数量的captainElevating
游戏对象拖到列表中,并非常容易地对其进行更改。协程方法的重复结构非常适合这种循环。