Як змусити гравця плавно ковзати по місцевості


11

діаграма

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

Я відчуваю, що я майже там, але не можу поставити останню частину на місце.

Оновлення: чудові новини всім! У мене це працює. Але ... я трохи розгублений, що я повинен нормалізувати, а що ні. Нормальний просто повинен бути одиничним вектором, правда? але потім я змішую це зі своїм вкладом, тому я нормалізую це - чи не помиляюся?

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

Відповіді:


13

Просто запроектуйте свій вектор руху на площину звичайного, а потім відніміть результат від вашого вектора руху.

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

Щось подібне все одно. Хоча у вашій прекрасній схемі вхід здається далеко від стіни, тому я трохи розгублений.


вибачте, що він повинен бути перед вертикальною стіною там. страшний малюнок
Iain

1
Я трохи розгублений з точки продукту. Не є точковим продуктом скаляр?
Iain

1
Так, але ви помножите його на нормальний (вектор), щоб отримати вектор вашого небажаного руху. Вектор (x, y, z), помножений на скалярний s, отримує вам вектор (sx, sy, sz).
Кріс Хоу

Виконано, змінили змінні, щоб сподіватися відповідати діаграмі. :)
Кріс Хоу

@Iain Я дуже намагаюся зрозуміти, як використовувати цю відповідь, але я не можу зрозуміти це. Коли я створюю такий точний код, я отримую дійсно дивні 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.