Как сделать так, чтобы игрок плавно скользил по местности


11

диаграмма

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

Я чувствую, что я почти на месте, но я не могу поставить последний кусок на место.

Обновление: отличная новость всем! У меня это работает. Но ... я немного запутался, что мне следует нормализовать, а что нет. Нормаль просто должна быть единичным вектором, верно? но затем я смешиваю это со своим вкладом, поэтому я нормализую это - я не прав?

Кстати, я также обнаружил, что мне нужно подтолкнуть игрока на 1 пиксель в направлении нормали, чтобы он не застрял на вещах - работает хорошо.

Ответы:


13

Просто спроецируйте ваш вектор движения на плоскость нормали, а затем вычтите результат из вашего вектора движения.

Vector undesiredMotion = normal * (dotProduct(input, normal));
Vector desiredMotion = input - undesiredMotion;

Как-то так или иначе. Хотя в вашей прекрасной диаграмме ввод, кажется, находится далеко от стены, поэтому я немного запутался.


извините, он должен быть перед вертикальной стеной там. ужасный рисунок
— Иан

1
Я немного запутался насчет точечного продукта. Разве точечный продукт не скаляр?
— Иэн

1
Да, но вы умножаете его на нормаль (вектор), чтобы получить вектор вашего нежелательного движения. Вектор (x, y, z), умноженный на скаляр s, дает вам вектор (sx, sy, sz).
— Крис Хоу

Готово, переменные изменены, чтобы, надеюсь, соответствовать диаграмме. :)
— Крис Хоу

@ Я действительно пытаюсь понять, как использовать этот ответ, но я не могу понять его. Когда я создаю этот точный код, я получаю действительно странные desiredMotionрезультаты. Вы когда-нибудь работали?
— тест

1

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

// assume that 'normal' is unit length
Vector GetDesired(Vector input, Vector normal) {
   // tune this to get where you stop when you're running into the wall,
   // vs. bouncing off of it
   static float k_runningIntoWallThreshold = cos(DEG2RAD(45));

   // tune this to "fudge" the "push away" from the wall
   static float k_bounceFudge = 1.1f;

   // normalize input, but keep track of original size
   float inputLength = input.GetLength();
   input.Scale(1.0f / inputLength);

   float dot = DotProduct(input, normal);

   if (dot < 0)
   {
      // we're not running into the wall
      return input;
   }
   else if (dot < k_runningIntoWallThreshold)
   {
      Vector intoWall = normal.Scale(dot);
      intoWall.Scale(k_bounceFudge);

      Vector alongWall = (input - intoWall).Normalize();
      alongWall.Scale(inputLength);

      return alongWall;
   }
   else
   {
      // we ran "straight into the wall"
      return Vector(0, 0, 0);
   }
}

Ницца. Но если вы масштабируете с помощью коэффициента выдумки, это заставит вас столкнуться со стеной, а не скользить вдоль нее, или это просто случай ее настройки?
— Крис Хоу

Я думаю, что вы настраиваете это, чтобы выглядеть хорошо; конечно, если он слишком большой, это будет выглядеть так, будто вы подпрыгиваете, но если он достаточно тонкий, он просто не даст вам застрять на небольших изгибах на поверхности.
— дэш-том-бэнг
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.