Камера від першої особи The Sims 4 з листопадовим оновленням
З листопадовим оновленням у гру була додана ще одна кумедна функція - камера від першої особи. Камера активується одночасним натисканням клавіш Shift+Tab і дозволяє досліджувати гру новим чином - очима своїх симів! При цьому ви зможете крутити головою Сіма і навіть взаємодіяти з об'єктами.
Гарячі клавіші
- Shift + Tab - Увійти в режим камери від першої особи / вийти з нього;
- Стрілка вліво / Стрілка вправо - Перемикання контрольованого сима в режимі камери від першої особи. Власники доповнення «Кішки та собаки» навіть можуть подивитись світ очима своїх вихованців!
- Ліва кнопка миші — взаємодійте зі світом та об'єктами;
- Права кнопка миші - Натисніть на дверях, щоб зайти за протилежний бік. Дозволяє переміщатися між кімнатами та поверхами;
- Shift (затисніть) - контролюйте курсор, перебуваючи в режимі камери від першої особи. Дозволяє взаємодіяти з інтерфейсом гри;
- Рух мишею - Переміщуйте камеру окремо від того, куди зараз дивиться ваш цим;
- Ctrl - Перемкніть камеру назад на напрям погляду вашого сима;
- Колесо миші - Змініть налаштування поля зору (нагоді, якщо вас заколисує);
- Tab — натисніть у режимі від першої особи, щоб приховати інтерфейс.
Подивитися як це виглядає та працює можна нижче.
Створення цього виду від першої особи в Unreal Engine 4
Технічний художник Фабрик Піке (Fabrice Piquet) з компанії Allegorithmic у блозі на сайті Gamasutra розповів, як у Unreal Engine 4 створити «справжній» вигляд від першої особи, при якій камера рухається відповідно до руху голови персонажа. Ми вибрали головне із матеріалу.
«Справжній вигляд від першої особи» передбачає, що камера «закріплена» на анімованому тілі персонажа, на відміну від простої камери, що «літає». Такий підхід використовувався, наприклад, у The Chronicles of Riddick, Syndicate та Mirror's Edge.
У «роздільній» системі дві руки персонажа незалежні від тіла та приєднані безпосередньо до камери. Це дозволяє безпосередньо анімувати руки для будь-якої ситуації та не турбуватися про те, що камера не слідує за руками. Решта тіла персонажа, як правило, це незалежний міш, що має власний набір анімацій. Мінус такого підходу в тому, що розробникам доводиться анімувати два набори моделей.
Іноді міші тіла видно тільки гравцям, а повна версія тулуба використовується для того, щоб малювати тіні (вона видно також іншим гравцям в мультиплеєрі, як останні Call of Duty). Це допомагає оптимізації, проте шкодить зануренню.
Міш повного тіла (Full-body Mesh) припускає, що весь персонаж складатиметься лише з одного міша. При цьому камера приєднана до голови. Її позиція чи обертання диктується рухами тіла, їх потрібно налаштовувати вручну. Ієрархія класу має такий вигляд.
PlayerContorller завжди знаходиться вище Character (або Pawn) в Unreal, тому тут нічого нового. У персонажа є міш тіла, у якого є AnimBlueprint для управління анімаціями. Нарешті камера, яка приєднана до міша в конструкторі. Однак, це не все.
Так як камера керується мішом, нам потрібно модифікувати або анімувати міш, щоб імітувати звичайні рухи камери, такі як погляд вгору, вниз, ліворуч і праворуч. Ці рухи створюються за допомогою додаткової анімації на один кадр.
Я використав 10 анімацій, але ви можете зробити і більше, якщо вам, наприклад, хочеться, щоб персонаж дивився назад. У моєму випадку разом з поворотом голови повертається і тіло (як у Mirror's Edge). Це вимагало створення додаткових анімацій.
Як тільки анімації імпортовані до Unreal, потрібно налаштувати кілька речей. Переконайтеся, що базова поза для анімацій названа правильно, щоб швидко знайти її, коли потрібно. Я назвав її anim_idle_additive_base.
Потім я відкрив інші пози і змінив кілька властивостей у вкладці Additive Settings. Параметр "Additive Anim Type" я встановив на "Mesh space", а "Base Pose Type" - на "Selected Animation". Нарешті я завантажив мою анімацію базової пози в слот ассетів. Усі ці дії треба повторити кожної пози.
Тепер, коли анімації готові, потрібно створити Aim Offset - ассет, який зберігає зв'язки між декількома анімаціями і дозволяє перемикатися між ними залежно від параметрів. Отримане додається поверх існуючої анімації (на кшталт бігу, ходьби тощо).
Мій Aim Offset враховує два параметри введення: Pitch та Yaw. Ці значення керуються оновленням ігрового коду.
Оновлення анімації
Щоб анімація оновлювалася, вам потрібно перевести дані, які вводить гравець, значення, зрозумілі для Aim Offset. Це робиться за три кроки:
- конвертація введення значення обертання у класі PlayerController;
- конвертація обертання, заснованого на світі, у локальне значення у класі Character;
- оновлення AnimBlueprint на основі значення локального обертання.
Крок перший: введення PlayerController
Коли гравець рухає мишку чи стики на геймпаді, я враховую введення в класі PlayerController і оновлюю обертання контролера, переписуючи функцію UpdateRotation().
Крок 2: локальне обертання камери
У мого класу Character є функція, яка називається PreUpdateCamera(). Вона робить таке.
Функції CameraProcessYaw() і CameraProcessPitch() конвертують обертання контролера значення локального обертання. Функції виглядають так.
Крок третій: оновлення AnimBlueprint
Останній крок найпростіший. Я отримую змінну локального обертання та передаю її AnimBlueprint, що має Aim Offset.
Як уникнути лага
Якщо ви дотримуєтеся цього гайду і не знайомі з тим, як працює функція Tick() у Unreal Engine, то ви ризикуєте зіткнутися з особливою проблемою – затримкою на один кадр. Це створює певний дискомфорт під час гри.
Все походить від того, що камера оновлюється після того, як будуть оброблені дані з минулого кадру. Якщо ви швидко переміщаєте погляд у грі, а потім різко зупиняєтеся, рух припиниться лише з наступним кадром. Таким чином, створюються помітні розриви незалежно від фреймрейту.
Щоб вирішити цю проблему, необхідно зрозуміти порядок, у якому функція Tick() викликається кожному класу. За замовчуванням це відбувається так.
Можна помітити, що клас Character оновлюється після AnimInstance (AnimBlueprint). Це означає, що локальне обертання камери обраховуватиметься лише на наступному тику, тому AnimBlueprint використовує старі значення. Щоб вирішити цю проблему, я розташував функцію «PreUpdateCamera()» в кінці тику PlayerController. Таким чином, система отримує свіжі дані про обертання до оновлення міша та його анімацію.
Відтворення анімацій
У такому вигляді вся система вже має працювати. Однак нам потрібно змусити її програвати конкретні анімації, застосовані до цілої справи. У цьому допомагає AnimMontages. Суть полягає в тому, щоб програти анімацію, яка переписує поточний AnimBlueprint.
У моєму випадку я хотів програти анімацію підйому через деякий час після падіння.