c# - 如何在 C# & Unity 中扩展使用二次插值创建的曲线?
问题描述
我正在尝试使用二次插值来在玩家的位置扔一块石头。岩石只是跟随曲线。但是,如果玩家移动,岩石就会开始循环并从原来的位置重新开始。一旦岩石到达曲线的末端,我就停止了沿着曲线移动的岩石并向岩石的刚体施加力,但它仅在特定示例中有效。我想知道是否有办法延长曲线,使岩石撞击地面并使用我已有的代码自行破坏。我正在使用的代码如下。提前致谢。代码如下。
二次插值代码(每帧运行一次)
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()
inside,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);
}
你运行一次,例如
private void Start ()
{
StartCorouine(FollowQuadraticPath());
}
或者Start
也可以是例程本身
private IEnumerator Start()
{
var startAB = TransformerPosition;
var targetAB = throwHeightPosition;
.....
}
您不必担心终止例程,因为它要么到达原始玩家位置然后被破坏,要么它之前撞到地面并被破坏。在任何一种情况下,协程也会自动消失。
不过,我真正不明白的是为什么您为此要进行 2 次额外的转换。为什么不简单地只用Vector3
自己计算
var ab = Vector3.Lerp(startAB, targetAB, interpolateAmount);
var bc = Vector3.Lerp(targetAB, targetBC, interpolateAmount);
transform.position = Vector3.Lerp(ab, bc, interpolateAmount);
推荐阅读
- php - 如何在 php 循环中正确运行 jquery 代码
- python - Numpy 数组就地更新或隐式复制
- java - 在控制器中映射 URL(从相关表中删除数据) Spring Boot
- javascript - Bootstrap 将样式应用于表单中不需要的输入。
- delphi - TidHTTP Request 在 Fiddler 运行时有效,但在关闭时无效
- grpc - gPRC如何将数组数据从服务器发送到客户端[gPRC + Node.js]
- d3.js - 如果要缩放,要计算缩放和平移的转换值
- css - mat-form-field 样式如何自动填充标签?
- python - 使用具有不同数据框形状的 matplotlib 绘制条形图
- powershell - 从 CMD 使用时如何正确引用 PowerShell 命令路径