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


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.