Мало объектов, движущихся по очереди в Unity - PullRequest
0 голосов
/ 26 января 2019

Я пытаюсь создать какое-то змееподобное движение, но я не могу реализовать алгоритм для перемещения одной части тела прямо за другой и т. Д.

Я хочу иметь несколько автоматически перемещаемых змей, состоящих изотдельные блоки (сферы).Эта змея должна двигаться по некоторому пути.Я сгенерировал путь с безлинейным сплайном и уже реализовал часть будущей змеи.Точка для головы получается из сплайна следующим 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 голосов
/ 26 января 2019

Для движения, похожего на змею, вы, вероятно, получите много странного поведения, если будете рассматривать сферы как отдельные объекты.Хотя я могу представить, что можно заставить его работать, я думаю, что это не самый лучший подход.

Первое, что приходит на ум, - это создать список, к которому вы добавляете индекс 0 на каждомкадр, положение головы змеи.Список будет расти, и все остальные сегменты будут ждать своей очереди, поэтому отстает от x кадров, и на каждом сегменте обновления у будет позиция списка [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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...