很少有对象在Unity中一一直线移动

时间:2019-01-26 18:42:58

标签: algorithm unity3d

我正在尝试创建一些类似于蛇的运动,但是我无法实现将一个身体部位笔直移动到另一个部位的算法,依此类推。

我想拥有一些自动移动的蛇,它由单独的方块(球体)组成。这条蛇应该沿着一条路径移动。我使用贝塞尔曲线样条生成路径,并且已经实现了一条未来的蛇形部分。头部的点是通过下一个api从样条线获得的:

class BezierSpline
{
  Vector3 GetPoint(float progress) // 0 to 1
}

而且我还没有SnakeMovement脚本

public class SnakeMovement : MonoBehaviour
{
  public BezierSpline Path;
  public List<Transform> Parts;
  public float minDistance = 0.25f;
  public float speed = 1;

//.....
void Update()
{
  Vector3 position = Path.GetPoint(progress);
  Parts.First().localPosition = position;
  Parts.First().LookAt(position + Path.GetDirection(progress));

  for (int i = 1; i < Parts.Count; i++)
  {
    Transform curBody = Parts[i];
    Transform prevBody = Parts[i - 1];
    float dist = Vector3.Distance(prevBody.position, curBody.position);

    Vector3 newP = prevBody.position;
    newP.y = Parts[0].position.y;
    float t = Time.deltaTime * dist / minDistance * curspeed;

    curBody.position = Vector3.Slerp(curBody.position, newP, t);
    curBody.rotation = Quaternion.Slerp(curBody.rotation, prevBody.rotation, t);
  }
  //....
}

就目前而言,如果我停止头部运动,那么所有零件都不会保持距离并继续移动到头部位置。上述算法的另一个问题是零件不会完全沿着头部路径移动。他们可以在转弯时“偷工减料”。 主要思想是仅对头部(第一身体部位)进行用户/人工智能控制,随后的每个部位都应正确重复头部路径并保持其邻居之间的距离。

1 个答案:

答案 0 :(得分:0)

对于像蛇一样的运动,如果将球体视为单独的对象,则可能会出现许多奇怪的行为。虽然我可以想象有可能使其工作,但我认为这不是最佳方法。

想到的第一个解决方案是创建一个列表,在该列表上将在每帧上添加蛇头位置到索引0。 列表将增长,所有其他段将等待轮到,因此延迟x帧,并且在每个更新段y上的位置为list [x * y]

如果列表的Count()大于number_of_segments * lag,则删除RemoveAt(Count()-1)

这可以优化,因为更改列表有些昂贵(环形缓冲区会更适合,但队列也可以工作。对于初学者来说,我发现列表更容易遵循,您以后可以随时进行优化)。如果您的帧率变化很大,但总体来说应该非常稳定,这可能会有些尴尬(例如-不会出现不可预测的运动,我们只会反复使用相同的值)

第二种方法: 您提到使用贝塞尔曲线样条生成路径。贝塞尔曲线由浮点t参数化,因此您有类似

SplineAt(t).

如果您使用bezier_path_length和distance_between_segments,则段n的位置应为

SplineAt(t-n*distance_between_segments/bezier_path_length)