问题描述
我正在尝试使用二次插值来向玩家的位置扔一块石头。岩石只是跟随曲线。然而,如果玩家移动,岩石开始循环并从其原始位置开始。一旦岩石到达曲线的末端,我就停止了它跟随曲线,并向岩石的刚体添加力,但它仅适用于特定示例。我想知道是否有一种方法可以延长曲线,使岩石撞击地面并使用我已有的代码自行摧毁。我正在使用的代码如下。提前致谢。代码如下。
二次插值代码(每帧运行一次)
private void FollowQuadraticPath()
{
interpolateAmount = (interpolateAmount + Time.deltaTime) % 1f;
pointAB.transform.position = Vector3.Lerp(transformerPosition,throwHeightPosition,interpolateAmount);
pointBC.transform.position = Vector3.Lerp(throwHeightPosition,playerPosition,interpolateAmount);
transform.position = Vector3.Lerp(pointAB.transform.position,pointBC.transform.position,interpolateAmount);
}
伤害
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.GetComponent<PlayerHealth>())
{
Destroy(pointABInstance);
Destroy(pointBCInstance);
collision.gameObject.GetComponent<PlayerHealth>().Dealdamage(damage);
Destroy(gameObject);
}
else
{
Destroy(pointABInstance);
Destroy(pointBCInstance);
Destroy(gameObject);
}
}
这就是我想要发生的事情。假装玩家已经移动,岩石会继续撞击地面,越过玩家点。
相反,再次假装玩家不在那里,物体在到达地面之前被摧毁
解决方法
我猜你在 FollowQuadraticPath()
中使用了 Update
,所以你总是在玩家的当前更新位置使用它。
相反,我会使用 Coroutine。协程有点像一个临时的更新方法,所以它有一个明确的开始和结束,你可以让局部变量在例程运行的所有帧中持续存在,并做一些事情,例如
private IEnumerator FollowQuadraticPath()
{
// Cash the target positions ONCE so they are not updated later
var startAB = TransformerPosition;
var targetAB = throwHeightPosition;
var targetBC = playerPosition;
// Iterates until 1 second has passed
// linearly increasing interpolateAmount from 0 to 1
for(var interpolateAmount = 0f; interpolateAmount < 1f; interpolateAmount += Time.deltaTime)
{
pointAB.transform.position = Vector3.Lerp(startAB,targetAB,interpolateAmount);
pointBC.transform.position = Vector3.Lerp(targetAB,targetBC,interpolateAmount);
transform.position = Vector3.Lerp(pointAB.transform.position,pointBC.transform.position,interpolateAmount);
// Tells Unity to "pause" the routine here,render this frame
// and continue from here in the next frame
yield return null;
}
// Destroy if it reaches the original player position
Destroy (gameObject);
}
你运行这个ONCE,例如在
private void Start ()
{
StartCorouine(FollowQuadraticPath());
}
或 Start
也可以是例程本身,如
private IEnumerator Start()
{
var startAB = TransformerPosition;
var targetAB = throwHeightPosition;
.....
}
您不必担心终止例程,因为它要么到达原始玩家位置然后被销毁,要么之前撞到地面并被销毁。在任何一种情况下,协程也会自动消失。
但我真正不明白的是为什么你有 2 个额外的转换。为什么不简单地只计算 Vector3
本身,如
var ab = Vector3.Lerp(startAB,interpolateAmount);
var bc = Vector3.Lerp(targetAB,interpolateAmount);
transform.position = Vector3.Lerp(ab,bc,interpolateAmount);