| Новости/News | | Туториалы/Tutorials | | Форум/Forum | | ЧаВо/FAQ | | Файлы/Downloads | | Ссылки/Links | | Авторы/About |
Unreal Physics 101
Содержание
Вступление
Цель этого туториала - "просветить" новичков о физике объектов в Анреаловском движке. Здесь нет практических советов, просто общая информация и объяснение - как это все работает и где применяется. Дока являет собой неплохой стартовый материал для более детального изучения физики объектов в движке.
Step 1 : Know your enumerations
Все типы физики объектов задаются перечислением EPhysics в классе Actor (для тех, кто не знаком с перечислениями, автор отправляет к доке UnrealScript Language Reference):
var(Movement) const enum EPhysics {
PHYS_None,
PHYS_Walking,
PHYS_Falling,
PHYS_Swimming,
PHYS_Flying,
PHYS_Rotating,
PHYS_Projectile,
PHYS_Rolling,
PHYS_Interpolating,
PHYS_MovingBrush,
PHYS_Spider,
PHYS_Trailer
} Physics;
|
Таким образом, всего у нас 12 "типов" физики объектов, хотя на деле - их всего 11 (Почему? Читайте дальше). Теперь перейдем ближе к делу.
Step 2 : PHYS_Huh?
- PHYS_None - как Вы, наверное, уже догадались - этот тип физики ничего не делает. С установленным PHYS_None Ваш объект не будет делать ничего полезного. Он будет просто оставаться на месте, пока Вы не зададите ему соответствующую скорость и направление. Никаких "фишек" и обработки траектории движения.
- PHYS_Walking - этот тип используется для потомков класса Pawn. В основном эта штука работает как признак движения Pawn`a по поверхности. Основная обработка PHYS_Walking происходит в native коде (функции непосредственно реализованные на C и "зашитые" в соответствующих dll библиотеках, для тех, кто не понял - native код - это код, который Вы не можете редактировать без исходников Анреаловского движка). Так, если объект (Pawn) находится не на сплошной поверхности, то его текущая физика меняется на PHYS_Falling. Если объект падает и приземляется на поверхность - его физика меняется обратно на PHYS_Walking. Этот тип физики "отвечает" за передвижение игроков в Unreal/Unreal Tournament. Основные переменные связанные с этой физикой: GroundSpeed (максимальная скорость передвижения Pawn`a по поверхности(земле)) и Acceleration (насколько быстро Pawn ускоряется до GroundSpeed).
- PHYS_Falling - это самый распространенный тип физики игровых объектов (несмотря на некоторое "сбивающее" название). Основное назначение - коррекция движения объектов в зависимости от действия гравитации. Опять же, все эти изменения проводятся в native коде, поэтому если даже Вы меняете вектор скорости объекта с помощью unrealscript в функции Tick (т.е. за единицу игрового времени), то коррекция траектории в соответствии с гравитацией зоны будет все равно.
- PHYS_Swimming - еще один тип физики для Pawn`ов предназначенный для создания "плавательного" эффекта (выталкивание из воды и пр.). Этот тип похож на PHYS_Flying (см. ниже) только в расчет еще берется параметр зоны FluidFriction (обрабатывается в native коде).
- PHYS_Flying - также используется для объектов класса Pawn. В native коде проделывается одна вещь - игрок может двигаться в любом направлении без влияния гравитации. Причем игрок все равно взаимодействует (collide) с объектами и геометрией уровня. Переменные, связанные с этим типом физики: AirSpeed (скорость передвижения в воздухе) и Acceleration (насколько быстро игрок ускоряется до AirSpeed).
- PHYS_Rotating - это для вращающихся объектов (оружие на земле, кулера и т.д.). Скорость и направление вращения задается при помощи параметра RotationRate (Movement).
- PHYS_Projectile - наряду с PHYS_Falling это также один из наиболее распространенных типов физики для игровых объектов. Объекты с этой физикой двигаются по простым прямолинейным траекториям в соответствии с установленным Velocity игнорируя гравитацию. Движение таких объектов достаточно предсказуемо и это отлично вписывается в концепцию сетевой модели Анреаловского движка (клиентская машина сама просчитывает траекторию движения объекта по заданному начальному положению и velocity - это позволяет снизить количество данных передаваемых по сети между сервером и клиентом). Переменные, задействованные в этом типе физики - AirSpeed и Acceleration (также как и для PHYS_Flying).
- PHYS_Rolling - тот самый "мертвый" тип физики - не используется.
- PHYS_Interpolating - этот тип физики сильно используется native кодом. В основном этот тип назначается для объектов, траектория которых просчитывается между двумя точками. Например, для Mover брашей между ключевыми кадрами (keypoints) или для передвижения объекта между двумя InterpolationPoints. Этот тип физики остается в основном за "ширмой" и вряд ли он Вам реально понадобится, разве что если Вы не создаете нечто специфическое.
- PHYS_MovingBrush - специально для Mover брашей (например, лифты, двери, платформы и т.п.). Обработка траектории таких объектов проводится в native коде.
- PHYS_Spider - название говорит само за себя (spider - паук). Объекты (точнее Pawn`ы) c этой физикой интерпретируют любую поверхность как "пол". Редкий тип физики (единственная пара примеров находится в паке UnrealI, классы ParentBlob и Bloblet).
- PHYS_Trailer - основная идея проста: объект с этим типом физики всегда будет находиться рядом со своим объектом владельцем (эта штука также обрабатывается в native коде). Переменные связанные с этим типом физики: bTrailerSameRotation (вращение объекта (rotation) будет таким же, как и у объекта владельца), bTrailerPrePivot (расположение объекта будет смещено относительно владельца на смещение заданное вектором PrePivot) и PrePivot (смещение от объекта владельца независимо от вращения последнего). Пример bTrailerPrePivot и PrePivot - класс TranslocGlow из пака Botpack.
Примечание: типы физики Falling, Swimming, Flying также часто используются для задания соответствующей анимации объекта (игрок, боты).
Step 3 : Physics in Action - Collisions
Теперь поговорим о том, как Движок определяет коллизии между объектами. Геометрия уровня по-другому называется BSP геометрией (BSP - Binary Space Partition), не вдаваясь в детали, достаточно будет сказать, что коллизии с геометрией уровня просчитываются по каждому единичному полигону (все понятно? :)). Для всего остального (для потомков класса Actor) определяется специальный Collision Cylinder. Т.е. у каждого объекта есть связанный с ним невидимый цилиндр определенных размеров, как только цилиндры двух объектов пересекаются, движок определяет что произошло столкновение этих двух объектов. Основные свойства каждого актера:
- CollisionHeight - высота collision цилиндра, измеряемая от актера до верхней грани цилиндра (актер находится в центре цилиндра). То есть на самом деле полная высота цилиндра будет 2 * CollisionHeight.
- CollisionRadius - радиус collision цилиндра.
- bCollideWorld - взаимодействует ли объект с геометрией уровня.
- bCollideActors - взаимодействует ли объект с другими актерами-объектами.
- bBlockActors - останавливает ли этот объект других актеров.
- bBlockPlayers - останавливает ли этот объект игрока.
Примечание: можно увидеть collision цилиндр в редакторе UnrealED. Для этого в заголовке окна выберите Actors->Radii View, затем добавьте какой-либо актер (например, любого из ScriptedPawn), выделив его, Вы увидите тот самый цилиндр.
Также обратите внимание, collision цилиндр не вращается вместе с объектов - он всегда статичен. Это очень упрощает производимые вычисления. Теперь, когда происходит коллизия, могут вызываться следующие функции:
- HitWall(vector HitNormal, Actor HitWall) - если bCollideWorld=True, то эта функция вызывается движком игры. HitNormal определяет нормаль (единичный вектор перпендикулярный плоскости) плоскости между соответствующим полигоном и объектом (вектор направлен к объекту). HitWall - актер, с которым наш объект столкнулся, например, если HitWall==Level - столкнулись с обычной геометрией уровня, если HitWall==Mover - столкнулись с Mover брашем.
- Landed(vector HitNormal) - если тип физики объекта - PHYS_Falling, то эта функция вызывается движком когда объект "приземляется" на поверхность при падении. HitNormal - нормаль поверхности, на которую приземлились.
- Bump(Actor Other) - если bBlockActors=True и bBlockPlayers=True, эта функция вызывается для обоих объектов в начальный момент времени столкновения.
- Touch(Actor Other) - если bCollideActors=True, эта функция, как и Bump, вызывается для обоих объектов, но не один раз, а каждый Tick (единица игрового времени), т.е. пока объекты взаимодействуют для них постоянно будет вызываться эта функция. При первом вызове этой функции создается массив Touching[ ], в который помещаются все актеры взаимодействующие с нашим объектом. Other также помещается в этот массив, если его там еще нет. Touching[ ] объявлен как const, т.е. Вы не можете менять его значения сами через скрипт.
- UnTouch(Actor Other) - если bCollideActors=True, эта функция вызывается для обоих объектов, как только их столкновение пропадает (вызывается только один раз).
В вызовах функции есть несколько особенностей. Иногда движок не вызывает обе функции Touch() и Bump() если оба объекта имеют свойство bBlockPlayers=True, вызывается только Bump(), а Touch() - нет. Если у одного объекта bCollideActors=True, а у другого bBlockActors=True, то для первого объекта (с bCollidingActors) вызовется Bump(), а для второго - Touch().
Заключение
На этом все. Надеюсь, этот тутор Вам помог в изучении основ физики объектов и коллизии, так что экспериментируйте и учитесь!
Автор
Оригинальная статья: Unreal Physics 101 c сайта CHiMERiC
Автор: Pfhoenix
Mail: pfhoenix@planetunreal.com
Web: mod exemplar
Вольный перевод: Shadow
Mail: shadow_m777@mail.ru