Войти
ПрограммированиеСтатьиФизика

Unity Character Motor

Автор:

Когда-то давно, еще во времена Unity 3, мне стало интересно как работает физика персонажа. И я заглянул в класс CharacterMotor. Класс был написан на JavaScript, был огромный, страшный и непонятный. Я решил переписать его на C#, попутно отрефакторив. Недавно я вспомнил про свой старый CharacterMotor, решил еще немного подправить его и поделиться им. Тем более, тема физики персонажа не очень популярная (я вообще не видел никакой информации), хотя довольно интересная.

1. Введение
2. CharacterController
3. CharacterMotor
4. CharacterMotor_Movement
5. CharacterMotor_Jumping
6. FPSInputController
7. MouseLook
8. Заключение

1. Введение

Я взял за основу CharacterMotor из Unity 3. В Unity 4 CharacterMotor не менялся, а вот в Unity 5, это абсолютно новый класс. Новый CharacterMotor, значительно уменьшился в коде, и видимо, и в функционале. Я не особо разбирался в нем и почти не использовал его, но заметил, что скольжение с крутого склона теперь не работает, и вообще качество кода мне не понравилось. Видимо писался он на скорую руку. Также Unity 5 перешел на новый PhysX 3, но в CharacterController я никаких изменений не заметил. Так что, думаю, мой CharacterMotor не устарел.

Character Motor | Unity Character Motor

2. CharacterController

Обычно персонаж не является обычным физическим объектом и работает по своим законам физики. В Unity для персонажа используется CharacterController. Это комбинация коллайдера в форме капсулы и метода Move. Метод Move двигает персонажа в указанную позицию, обрабатывая при этом коллизию. Обработка коллизии тут тоже не обычная, например, коллизия обрабатывается так, чтобы персонаж мог свободно подниматься на небольшие склоны, но не мог на большие, или auto stepping - фича, которая позволяет персонажу подниматься на маленькие препятствия. CharacterController не совместим с RigidBody, это значит, что он не может взаимодействовать с другими физическими объектами. Это создает некоторые проблемы: персонаж не может двигать другой физический объект, а другой объект не может сдвинуть персонажа. Кинематические объекты вообще свободно проходят сквозь персонажа, что делает проблематичным создание лифтов и движущихся платформ.

3. CharacterMotor

Вместо RigidBody мы должны использовать свой класс, в Unity это CharacterMotor. Хотя, CharacterMotor — это намного больше, чем RigidBody. CharacterMotor отвечает за любые движения нашего персонажа, например: ходьба, бег, скольжение, падение, прыжки, движение на платформе, на лифте, подъем по вертикальной лестнице, плавание. Все это реализуется, фактически, с помощью различных ухищрений, а не законов физики. Ведь персонажи обычно ведут себя не по законам, например: персонаж может немного управляться во время прыжка или падения, или просто резко останавливаться или менять направление движения. В Painkiller Дэниел мог ускоряться, просто прыгая без разбега. Конечно это все не сильно нарушает законов игровой физики, и можно было бы попытаться сделать максимально все физически корректно, но ведь проще просто ограничить скорость падения, чем вычислять сопротивление воздуха.

Я разделил мой CharacterMotor на 3 partial класса: CharacterMotor, CharacterMotor_Movement и CharacterMotor_Jumping. В оригинальном классе был еще класс отвечающий за движение на платформе, но я убрал его.

Базовая часть CharacterMotor реализует следующие:

+ Показать

4. CharacterMotor_Movement

Эта часть класса отвечает за движения и гравитацию, и реализует следующие:

+ Показать

5. CharacterMotor_Jumping

Это последняя часть класса, ответственная за прыжок. Она реализует фактически один ApplyJumping, в котором есть пара особенностей:

+ Показать

6. FPSInputController

Чтобы сделать полноценного, управляемого персонажа, нам нужно еще пара вспомогательных классов. Первый – обрабатывает ввод. Этот класс очень простой, но в нем есть две особенности:

Кстати, FPS расшифровывается, по идее, как first person shooter.

+ Показать

7. MouseLook

Это последний и простейший класс, ответственный за вращение камеры. Точнее, камера вращается только по оси X, а по оси Y вращается весь персонаж.

+ Показать

8. Заключение

Я переписал эти юнити скрипты практически до неузнаваемости, что-то добавил, что-то удалил, но тем не менее принципиально ничего не изменилось. Оригинальные скрипты для Unity 4 и 5, вы можете посмотреть в корне репозитория. Код, надеюсь, я довел до нормального состояния. Но, как я сказал, принципиально ничего не изменилось, то некоторые вещи мне не нравятся. Также есть еще много вещей, которые можно было бы добавить. Поэтому я буду стараться обновлять репозиторий, и буду рад вашим комментариям и предложениям.

Заметил пару багов. Когда CharacterController стоит на сфере, то нормаль поверхности сферы направлена внутрь сферы. Из-за этого персонаж не понимает, что он стоит на земле. На втором видео, в момент 3:07, видно странное разрешение коллизии, которое приводит к тому, что CharacterController резко толкается вниз, когда напрыгивает на такую платформу.

Официальный гид по CharacterController: http://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/g… trollers.html

Репозиторий: https://bitbucket.org/dddenisss/unity-character-motor

#Unity, #Unity3D

29 июня 2016 (Обновление: 26 июля 2016)

Комментарии [61]