Як уберегти FPS-камеру від Quaternion від нахилу та псування?


17

Я використовую FPS-подібну камеру, і вона використовує кватерніони. Але кожен раз, коли я намагаюся дивитись вгору, а потім набік, він нахиляється, а іноді може перевертатися догори дном. Як я можу це виправити?


Відповіді:


16

Ви можете розкласти кватерніон на кут нахилу / нахилу / нахилу кутів, але це зазвичай надмірно.

Замість того, щоб складати свої кватерніони так:

cameraOrientation = cameraOrientation * framePitch * frameYaw;

Спробуйте це:

cameraOrientation = framePitch * cameraOrientation * frameYaw;

Тоді він ніколи не створюватиме нахил / нахил і є рівносильним для зберігання посіву та нахилу окремо


3
Це. Це саме те, що я шукав. Вирішив мою проблему в одноколірному. Приємно!
aardvarkk

1
Є framePitchі frameYaw floatтипи? Також я буду вдячний вам за деякі роз’яснення щодо вашого першого речення.
sirdank

1
@sirdank cameraOrientation, framePitchі frameYawвсі кватерніони (кожен кватерніон - 4 поплавця або парні).
Ден

8

Це проблема, яку я мав деякий час, і я не зміг знайти відповіді, тому думав, що опублікую її тут.

Це насправді досить просто. Як ви, швидше за все, робите обертання, так:

currentDirection * newRotation;

Але робити це так не працює.

newRotation * currentDirection;

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

Для мене це було так:

        if (keyboard.IsKeyDown(Keys.Up))
            Direction = Direction * Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), TurnSpeed);
        if (keyboard.IsKeyDown(Keys.Down))
            Direction = Direction * Quaternion.CreateFromAxisAngle(new Vector3(-1, 0, 0), TurnSpeed);
        if (keyboard.IsKeyDown(Keys.Left))
            Direction = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), TurnSpeed) * Direction;
        if (keyboard.IsKeyDown(Keys.Right))
            Direction = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, -1), TurnSpeed) * Direction;

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


Мені довелося чекати 7 годин, щоб відповісти на своє ...
Аеодін

Вибачте, чи можете ви пояснити це за допомогою деяких знімків екрана? "перший порядок" та "другий порядок" трохи заплутані - дякую!
Atav32

Під час роботи з Quaternions порядок має значення, як це завжди робиться з тривимірними обертаннями. У моєму прикладі "Направлення * = newRotation" те саме, що "Direction = Direction * newRotation". Але, обертаючи ліворуч і праворуч, ми хочемо, щоб це було навпаки. Це робить його не залежним від нахилу вгору та вниз, що спричиняє кочення.
Aeodyn

О, хоч справа, що чверть четвертинців полягала в тому, що він уникав фіксації карданних і обертання були незалежними, але я, можливо, неправильно прочитав підручник. Тож для уточнення ви хочете сказати, що якщо ви скасуєте порядок перетворень обертання, ви можете запобігти нахилу камери? Або ви вручну встановлюєте перетворення нахилу та нахилу на 0 при повороті повороту?
Atav32

5

Для камери FPS ви, як правило, не хочете котитися і обмежуються +/- 90 градусами крок, тому я просто слідкуватиму за поточним станом, використовуючи кути нахилу та нахилу. Повна потужність кватерніонів не дуже допомагає для цього.

Ви все ще можете перетворити кути нахилу / нахилу в кватерніони та з них, якщо ви хочете перейти між камерою FPS та анімованими камерами, використовуючи інтерполяцію кватерніонного кадра або щось подібне.


0

Ще один простий трюк - поставити камеру в GameObject і дозволити обертання Yaw контролювати ігровий об’єкт, тоді як дочірня камера налаштована з координатами Pitch:

playerCameraHolder.transform.Rotate(0, rotationYaw, 0);
playerCamera.transform.Rotate(rotationPitch, 0, 0);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.