Как сделать нпс в юнити 3д

Обновлено: 07.07.2024

Почему один обьект проходит сквозь другой хотя у меня есть коллайдеры на обоих обьектах?

Почему мой персонаж во время движения проходит сквозь другой обьект, а потом его откидывает назад?

Как реализовать передвижение персонажа в Unity3d правильно?

Почему так часто используется передвижение через transform.position и почему это неправильно?

Почему мой персонаж движется с разной скоростью если проседает FPS?

Почему используя присвоение в transform.position используют множитель Time.deltaTime ?

Почему двигать персонажа через смену transform.position неправильно?

Почему при использовании Velocity или .AddForce() не используется множитель Time.deltaTime ?

Как сделать прыжок от пола, но так что бы персонаж не мог бесконечно взлетать

Почему когда платформа движется, персонаж стоящий на платформе остается на месте?

Почему пуля не всегда наносит урон?

Все эти вопросы, фактически, являются одним единым вопросом, который слишком уж часто встречается у начинающих.

Заодно создал тэг unity3d-faq


1 ответ 1

В любом случае на персонаж должен быть навешан RigidBody - скрипт отвечающий за физику персонажа (силу притяжения, силу трения и т.д.)

Хоть я здесь и разбираю в т.ч. нефизическое движение, я настоятельно рекомендую использовать ФИЗИЧЕСКОЕ движение. И переходить на нефизическое только в исключительных ситуациях.

В коде не должно быть прямой привязки к кнопкам. Должна быть привязка к параметрам Input Manager . Которые можно найти в: Edit -> Project Settings -> Input . Нужно принять это как аксиому и не отходить, несмотря, на то что вы там нагуглите.

Я буду использовать здесь 2 термина: "телепортация" и "плавное движение". В моем понимании:

Плавное движение - перерасчет позиции обьекта в рамках физики или паралельно физике на вызове FixedUpdate() .

Телепортация - перерасчет позиции обьекта на промежутке времени большем чем fixedDeltaTime .

Есть люди у которых мнение отличается.

  • Плавное движение - исключительно физическое движение
  • Телепортация - изменение позиции вручную или использование .Translate() метода.

Учтите, что все что написано ниже упирается в верхние значения терминов, а не эти.

Двигать обьекты в игровых движках можно следующими способами:

используя физический движок (движение обусловленное физической моделью игрового движка)

движение НЕфизическое. Неправильный подход -- подход телепортации на каждом кадре. (в Update() )

движение НЕфизическое. Правильный подход -- плавное передвижение обьекта между кадрами (паралельно каждому просчету физики) (все равно желательно не использовать)

Движение реализуемое через CharacterController (здесь пока что не рассматривается т.к. новички в его сторону вообще не смотрят, может, позже распишу)

На практике метод передвижения подбирается под конкретного персонажа[персонажа -- не буквально. Это может быть и автомобиль]. В одном случае лучше будет физическое перемещение. В другом -- нефизическое. В третьем случае будет лучше всего CharacterController. Понимание что лучше в каком случае прийдет с практикой.

Новички очень часто использую телепортацию на каждом кадре, что есть критически неправильным подходом. Потом на SO появляются кучи клонов вопросов вроде "почему персонажа дергает возле стены?" или "почему он проходит сквозь стену?" или "почему пуля не всегда наносит урон?" и подобные.

Нужно запомнить всего одно правило: Двигать/поворачивать через присвоение transform.position / transform.rotation нельзя. Это порождает проблемы. В любом случае это вам вылезет боком.

Все для чего нужно это -- телепортация в другое место обьекта, но никак не его движения.

( на примере обьекта-шара )

Обратите внимание что за основу взят код из официальной документации/туториалов по юнити. Если есть несколько источников информации по какому-то мелкому но часто задаваемому вопросу (например движение персонажа ) -- выбирайте официальную документацию! Там точно фигни не посоветуют,

Есть Update() -- этот метод вызывается на каждой прорисовке кадра. Time.DeltaTime - это расчетное время между прорисовкой двух кадров. Если FPS проседает на компьютере, то этот параметр возрастает пропорционально проседанию.

Есть FixedUpdate() - это метод который вызывается при перепросчете физики. Time.FixedDeltaTime , как вы уже догадались, это время между вызовами FixedUpdate() . Оно может изменятся вручную через настройки, но упирается в физические возможности машины на которой игра будет запущена.

Если обьект не обладает физическими свойствами (не имеет RigidBody) эти параметры и методы можно использовать для НЕфизического передвижения.

Например поворот камеры.

Или крутящийся куб на небосводе.

Или движущийся изображение поезда где-то далеко, к которому нельзя подойти близко. Физика такому обьекту просто ни к чему -- это просто лишняя трата ресурсов

но, даже, в этом случае предпочтительно использовать Transform.Translate , но про это позже

Мы не получим дергающуюся картинку при проседании кадров если сделаем НЕФИЗИЧЕСКОЕ движение правильно:

ВАЖНО: . ПРИМЕР ВРЕДНОГО КОДА. Не делайте так!

мы присваиваем в новую позицию:

  1. старую позицию
  2. направление движения
  3. скорость передвижения умноженную на Time.deltaTime .

Поэтому, даже, если, у нас было 60 кадров и случилось проседание до 10 кадров -- скорость вращения/движения обьекта не будет изменятся. Ведь, мы ее учитываем вместе с проседанием кадров.

Допустим мы двигаем обьект через rb.Velocity или через AddForce() , то это физическое движение обьекта. То есть она может изменятся во времени сама под действием неких физических законов. Например, мы задумали сделать прыжок персонажа:

мы разово задаем вектор скачка. Только 1 долю секунды. Но он будет изменятся во времени автоматически равномерно уменьшаясь под силой тяжения. Пока не станет нулевым (верхняя точка прыжка), а потом не пойдет в минус по Y (падение), а потом не упадет на землю и не отскочит от нее (снова плюс по Y ) и так до полной остановки физической скорости обьекта на земле.

Допустим, мы двигаем изменением transform.Positon нашего плеера вперед по нажатию клавиши "пробел". В какой-то момент мы перестаем нажимать кнопку -- движение резко остановится и замрет. Это потому, что наше движение НЕ является физическим. Допустим мы подойдем к стенке и попробуем пройти на нее. Т.к. мы занимаемся телепортацией обьекта, то наш персонаж сначала дойдет до стенки, а потом телепортируется ВНУТРЬ нее, после чего Collider ее вытолкнет из себя. Как глубоко телепортируется внутрь зависит лишь от того, на какое расстояние мы телепортируем нашего персонажа за кадр. То есть это "Bad Practice" так реализовать перемещение персонажа.

Но в то же время есть и допустимое не-физическое перемещение. Это использование метода Transform.Translate() . Это (вроде как) тоже телепортация, но с попыткой плавного нефизического перемещения обьекта. Но использование этого метода не освобождает нас от использования deltaTime/fixedDeltaTime, как в примере оф.документации.

( Снова таки - если на вашем обьекте есть RigidBody - наверняка нужно использовать физическое перемещение все равно! )

Если девайс с игрой сильно загружен, вызов методов Update() / FixedUpdate() тоже может просесть в скорости. И если в физике это учтено и без нас, то сейчас мы делаем НЕ физическое движение и именно по-этому это нужно учитывать добавлением даного множителя.

Но и без использования даного множителя у нас не появится проблем с провалами сквозь стены. Это просто фикс скорости.

Если в прошлом примере мы двигали шар, то было допустимо его толкать используя физ.модель. То есть мы использовали AddForce() для этих целей.

Допустим у нас персонаж -- человек, а не шар. Давай создадим вместо человека его подобие -- высокий куб 0.8х1.8х0.3 и попробуем нацепить на него наш скрипт движения шара. Выйдет следующее:

То есть когда мы пытаемся подвигать, наш персонаж падает (мы ж его толкаем, логично!). Когда он упал -- он не может двигатся из-за силы трения. Зато мы можем двигать его в прыжке. :)

Давайте актуализируем этот код под даного персонажа. Мы заменим физический толчек обьекта на не-физическое, но ПЛАВНОЕ перемещение обьекта в пространстве:

С этим кодом мы получим такой результат:

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

Теперь мы можем занятся украшательствами -- например повороты тела. Довольно приятно реализованы повороты вот здесь: Как сделать управление, как в игре "Overcooked"?

Так же можно добавить анимацию бега на нашего персонажа (ну если бы это был не куб).

Да, можно подобное реализовать и на физике.

Наша прошлая версия скрипта имела несколько недостатков. А именно:

  • нужно было вручную отмечать каждый из предметов от которого мы можем прыгать. То есть добавив ящик на пол, нам нужно еще и его отметить тэгом Ground.
  • если поставить кучу ящиков вертикально, присвоить каждому из них тэг "Ground", то просто подойдя к вертикальной стене из ящиков мы сможем взлететь вверх). То есть нам не важно к чему мы дотрагиваемся -- к полу или к стене -- оно давало нам возможность прыгать.
  • наше движение все так же было НЕ физическим. То есть если мы начнем двигать игрока влево-вправо то он будет резко останавливатся а потом резко двигатся в противоположную сторону. В живом мире так не бывает.

Вспомните уроки физкультуры, когда нужно было пробежать 30 метров вперед, взять палочку, пробежать 30 метров назад, положить палочку и еще раз 30 метров в другую сторону. Что случалось с бегуном в этот момент если посмотреть сбоку? Сначала скорость растет, потом достигает пика, а потом торможение, взятие палочки, бег в другую сторону -- снова возрастание скорости. Никаких резких скачков. Этого можно добится именно передвижением при помощи физики.

Давайте поместим на наш куб CapsuleCollider (минимальное торможение из-за силы трения) и заблочим в rigidBody rotateX и rotateZ (что б наш персонаж не падал на бок).

А потом нацепим на него вот этот скрипт:

Вы видите эту плавность, как будто человек бежит, останавливается, бежит в другую сторону? Красота!

А теперь вернитесь к прошлой гифке и присмотритесь. Движение совсем не такое :) Там как буд-то рукой двигают шахматную фигуру по доске.

Ну и описанные выше баги поведения были пофикшены с такой реализацией.

Можно добавить еще физический материал нашему персонажу и откоректировать его поведение.

Вообще улучшать реализацию можно до бесконечности. Но, думаю, основные проблемы СПОСОБОВ ПЕРЕДВИЖЕНИЯ с которыми вы столкнетесь, я затронул :)

Оптимально использовать именно передвижение на базе физики.

Пытайтесь использовать исключительно физическое передвижение.

Одним из моих любимейших примеров нестандартной физики движения является игра Ori and the Blind Forest

Такое перемещение/такие прыжки невозможно сделать на основе стандартной физики. Вероятнее всего, это делалось через физическое перемещение + костыли для получения нужных эфектов которые противоречат стандартной физике.

Сначала разрабатываются концепты движения. Они делаются в любом видеоредакторе с примитивными фигурами. Вот пример (если станет недоступным искать можно по Ori and the blind forest Enemy Concepts ) :

Обратите внимание на то, то здесь прорисовано не только перемещение обьекта, но и его вытягивания/сжатия. Изменения формы во время любого взаимодействия с внешним миром. В т.ч. выстрелы так же влияют на форму. А так же что указываются радиусы опознавания главного героя каждым отдельным врагом.

Костыли для каждого персонажа/врага свои собственные. Это делается что бы каждый из них обладал своей уникальной физикой. Сделать это на общей физике навряд ли возможно.

ДАЖЕ если вы реализовали физическое передвижение вашего персонажа, все равно может случится такое, что просчет CollisionDetect может проходить с ошибками. Такое бывает.

Для таких случаев есть настройки отвечающие за обработку CollisionDetect в настройках самого RigidBody.

введите сюда описание изображения

Желательно такого не делать т.к. это негативно сказывается на производительности. Чем на большем количестве обьектов вы меняете эти настройки, тем более вероятно что вы делаете какую-то дичь, которую делать совсем не нужно. Считайте это спасательным кругом, а не панацеей. А если вы так будете делать, то рано или поздно вы прийдете на SO с вопросом почему игра тормозит, вас попросят показать код и ничего не найдут просто потому, что проблема тормозов не в коде. И намучаетесь вы с оптимизациями ой как сильно.


Итак. Всем привет. И сегодня я расскажу, как сделать простое движение персонажа. Сейчас только от третьего лица… Приступим…
Начнём, пожалуй, с создания персоажа. У меня это будет куб. Кто не знает, как создавать кубы или круги, поясняю – “GameObject” => “CreateOther” => “Cube”. Создаём таким же образом камеру и привязываем к кубу (то бишь просто в иерархии перетаскиваем камеру на куб).
Так… Теперь создадим поверхность, по которой персонаж будет ходить. Пусть это будет просто “Plane”. Ах, да… В конце урока будет ссылка с исходником по туториалу для тех, кто не понял.
Итак. Теперь создадим скрипт “Move”. Добавим переменную игрока и переменную скорости.

NPC (Non-Player Character) - это персонаж, который не находится под контролем игрока. Поведение неигрового .

Таймкоды: 00:00 - Вступление 00:06 - Разбор алгоритма 02:58 - Настройки скрипта 04:20 - Обзор кода 07:58 - Конец .

Всем привет. На канале будут выходить подобные видео в которых я просто буду показывать какие-то реализации в .

В этом видео я покажу как сделать ИИ врага таким образом, чтоб у него было три состояния: патрулирование, .

Это пятая часть моего курса туториалов по Unity для абсолютных новичков, в результате которых у нас получится 2D .

Привет! В этом видео покажу как создать искусственный интеллект в юнити. Желаю вам приятного просмотра! MultiVR .

В этом видео я покажу вам как сделать бота у которого будет зона видимости (зрение) и когда игрок попадёт в нее (когда .

Привет друзья! Сегодня я вам покажу как добавить персонажа в Unity, который будет бегать и прыгать. Это важная часть .

В этом туториале по единству мы начинаем добавлять немного ИИ нашему NPC, чтобы он бродил по городу. ✦ Подпишитесь: bit .

В этом уроке, я продемонстрирую один из способов, как создавать диалоговую систему в Unity. Так же покажу как .

Хочешь выучить Unity (юнити) всего за 1 час и при этом сделать это качественно? Тогда смотри от профессионала как!

В этой серии: Уроки по Unity 3D,создание врага,анимация атаки,урон,переход на следующий уровень,,шкала здоровья .

С помощью системы Nav Mesh можно сделать множество вещей связанных с перемещением объектов в игре - управление .

В этом уроке мы разберем, как задать патрулирование персонажу по определенным точкам или маркерам, которые он .

Хотите создать 3D гонку в Unity или просто управление машиной, но не знаете как? Тогда смотрите 3 способа, как это .

В этом уроке я покажу как сделать слежения объекта за нашим персонажем. Кроме того, исправим недочеты того, чтоб .

Тайм-коды: 00:00 - Демонстрация геймплея Hopeless World в Unity 00:16 - Блокаут уровня в Unity с помощью ProBuilder 1:07 .

This video shows how you can use the NPC Populator to easily create a lot of free-roaming humanoid NPCs (non-player .

Фанаты NFS, FlatOut, Forza, Dirt, Burnout и других гонок, ПРИСТЕГНИТЕСЬ! Макс сделал гонку на Юнити! Главное, .

В этом видео я продолжаю делать Top-Down шутер на движке Unity. Покажу как добавить в игру подбор бонусов: зелье .

Создание игр. В этом видео я покажу первый квест в моей игре, новых врагов и нпс, а также расскажу немного о самой игре.

Существует три главных шага по созданию “с нуля” своего анимированного гуманоидного персонажа: моделирование, риггинг и скиннинг.

Моделирование

Это процесс создания своих гуманоидных мешей в одном из инструментов 3D моделирования - 3DSMax, Maya, Blender, и т.д. Хоть это и целая тема для обсуждения сама по себе, существует несколько принципов, которые рекомендуется соблюдать, чтобы ваша модель была совместима с анимацией в Unity проекте.

  • Соблюдайте разумную топологию. Понятие “разумной” структуры вашего меша довольно тонкое, но в целом вам следуем помнить о том, как вершины и треугольники модели будут искажаться при анимации. Неправильная топология приведёт к неприятным искажениям меша при движениях модели. Изучая существующие 3D меши персонажей, можно узнать много нового о том, как правильно размещать топологию и почему.
  • Не забывайте про масштаб вашего меша. Попробуйте импортировать модель и сопоставить её размер с “метрическим кубом” (длина одной стороны стандартного Unity примитива “куб” равна одной условной единице, так что такой примитив можно рассматривать как однометровый куб в большинстве случаев). Проверьте единицы измерения вашего приложения для 3D моделирования и скорректируйте настройки экспорта так, чтобы размер модели был в нужных вам пропорциях к метровому кубу. Если не учитывать это при работе над моделями, легко прийти к ситуации, когда вы создадите несколько разных моделей без учёта масштаба и они окажутся несоразмерны после импорта в Unity.
  • Располагайте меш так, чтобы ступня персонажа находилась в центре вращения модели. Так как обычно персонаж ходит по горизонтальной поверхности, будет намного проще с ним работать, если его центр вращения(то есть, его позиция трансформации) будет на этой поверхности.
  • По возможности, моделируйте в Т-позе. Это даст дополнительное пространство для манёвра при работе над труднодоступными местами (например, подмышками). Кроме того, это упростит размещение рига внутри меша.
  • Держите модель в порядке. Не оставляйте дырок в поверхности, объединяйте вершины и избавляйтесь от скрытых поверхностей, которые никогда не будут видны. Это поможет при скиннинге, особенно если скиннинг автоматизирован.

Риггинг

Это процесс создания скелета из сочленений для управления движениями вашей модели.

Программы для 3D моделирования предоставляют множество инструментов создания сочленений гуманоидного рига. От уже готовых скелетов, которые достаточно отмасштабировать под свою модель, до средств создания отдельных костей и объединения их в костную структуру. Чтобы риг работал с Mecanim, таз должен быть корневым элементом всей иерархии костей и в скелете должно быть не менее 15 костей.

Иерархия сочленение/кость должна соответствовать натуральной структуре создаваемого персонажа. Поэтому руки и ноги должны идти в парах и вам следует соответствующе их называть (напр. “arm_L” для левой руки, “arm_R” для правой и т.д.). Возможные структуры иерархии:-

  • Таз - позвоночник - грудная клетка - плечи - рука - предплечье - кисть
  • Таз - позвоночник - грудная клетка - шея - голова
  • Таз - бедро - нога - ступня - палец - конец_пальца

Скиннинг

Это процесс привязки меша к скелету.

Скиннинг включает в себя связывание вершин в вашем меше с костями скелета. Вершина может быть связана с костью напрямую (жёсткая привязка) или с несколькими костями, используя на них смешанные воздействия (мягкая привязка). В разных программах используются разные способы, например, привязывание отдельных вершин и вписывание в меш степени воздействия на каждую кость. Изначальная настройка обычно автоматизирована, к примеру, с помощью поиска ближайшего воздействия, или с помощью “heatmap”. Обычно скиннинг требует изрядного количества работы и тестирования с помощью анимаций, чтобы достичь желаемых результатов деформации скина. Вот несколько основных рекомендаций для этого процесса:

Читайте также: