Как сделать меч в юнити

Добавил пользователь Владимир З.
Обновлено: 04.10.2024

Из этого туториала вы узнаете, как создать игру с использованием Unity3D! Попутно вы узнаете о важности использования физического движка и о том, как это сэкономит бесчисленные часы ручной анимации. Читай дальше!

Какой современный игровой движок будет полным без физического движка? Каждый текущий игровой движок, будь то 3D или 2D, имеет какую-то физическую библиотеку, и Unity не является исключением. Физика в реальном времени идеально подходит для моделирования сложных взаимодействий между объектами в вашей игре. Физический движок может сэкономить много ручного кодирования и анимации для достижения реалистичного движения, может упростить выполнение обнаружения ударов и быстро внедрить множество новых игровых механизмов в ваши игры.

В этом уроке мы будем использовать физический движок в Unity для создания трехмерной игры, похожей на BoomBlox и Angry Birds. Мы научимся придавать объектам разные физические свойства, делать их способными к столкновению и даже позволять им разрушаться, если столкновения достаточно сильны.

Финальная игра

Что такое физический движок?

Настройка проекта

Коллайдеры

Удобно, когда бы ни создавался GameObject, ему автоматически назначается соответствующий коллайдер. Куб получает BoxCollider, Сфера получает SphereCollider, Цилиндр получает CapsuleCollider и так далее.

Коллайдеры

В конечном итоге нам понадобится несколько блоков, чтобы сбить:

Если мы нажмем Play, блок ничего не сделает. Хотя у него есть коллайдер, у него нет твердого тела, поэтому на него не влияют никакие физические силы.

Rigidbodies

Твердое тело — самый важный элемент физического движка. Любой GameObject, к которому он прикреплен, включается в симуляцию.

Компонент твердого тела

По умолчанию на твёрдое тело влияют сила тяжести и сопротивление воздуха, также известное как сопротивление. Если мы нажмем Play, блок начнет падать, ускоряться и в конечном итоге достигать конечной скорости, когда сила тяжести и сопротивление уравниваются.

Построить структуру

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

Земля автоматически получит MeshCollider, который будет препятствовать прохождению любых твердых тел через нее. Нажмите Play, и блок должен упасть и осесть на землю.

Сила тяжести

Теперь нам нужна структура, чтобы сбить с ног. Выберите блок и нажмите Ctrl + D в Windows или Cmd + D в OSX, чтобы дублировать блок несколько раз. Используйте инструменты масштабирования и перемещения, чтобы растянуть и расположить блоки примерно в той же конфигурации, что и на рисунке ниже.

Павел Попов — Senior Unity Developer в команде NIX. В течение восьми лет он взаимодействует с архитектурой проектов и сетевой составляющей, а также периодически делает инди-игры. Знаком со стеком разработки с нуля, включая наброски картинок. Для ArtCraft Media Павел написал подробный туториал о том, как создать и анимировать 2D персонажа с помощью Unity 2020 LTS и пакетов PackageManager.

Павел Попов — Senior Unity Developer

Почему Unity?

Выбор пал на эту технологию потому, что в ней у меня больше опыта. Средства Unreal Engine, например, лучше всего использовать в 3D-разработке. Godot вполне в силах потягаться с Unity, но там еще есть нюансы с производительностью и стабильностью. Adobe Animate или Toon Boom Animation — для тех, кто рисует покадрово, например, для художников и профессиональных аниматоров.

Мы же нацелены на автоматизацию, и применение этих анимаций в играх или кат-сценах. Так мы сможем управлять широким спектром составляющих картины, не прибегая к прорисовке каждого кадра, а используя сам движок и наработки: освещение, эффекты, симуляции боев и тому подобное.

Пока еще на Unity из коробки проще выдать хороший результат. Разработчики регулярно обновляют пакеты с исходниками, и дают возможность кастомизировать продукт под себя.

Сейчас мы создадим готового к анимации персонажа средствами Unity из картинки, разбитой на части. Освоив описанные ниже инструменты, ты сможешь оживить любую картинку, привести в нужный вид персонажа и также оживить его. Кроме того, в будущем ты будешь гораздо точнее ставить задачи художникам. Итак, погнали!

Начальная настройка Unity

Поставив 2D PSD Importer, за ним подтянется 2D Animation, который нам понадобится для инверсной кинематики (далее IK). Далее все, что нам нужно — правильно настроенный арт, и здесь есть свои тонкости. Возьмем для наглядности программу Gimp (последующие действия идентичны для Photoshop).


Используемые пакеты (Окно PackageManager (Windows->PackageManager). Источник: личный архив автора

Разбиваем персонажа на слои в Gimp (или Photoshop)

Персонаж, разобранный по слоям в Gimp. Источник: личный архив автора

Персонаж, разобранный по слоям в Gimp. Источник: личный архив автора

Если используешь Photoshop, выбери при экспорте формат .psb. Если Gimp, то экспортируем .psd, и потом вручную меняем формат файла на psb в проводнике. Они отличаются большим объемом поддерживаемого разрешение вплоть до 300 000 x 300 000 в отличии от обычного .psd (30 000 x 30 000). Если кидать обычный формат (.psd), Unity его не увидит. Перейдем к самому интересному инструменту с пакета PSD Importer.

Настройка персонажа в Unity

Благодаря PSD Importer пакету мы видим дополнительные возможности — Secondary Textures. Они нужны, чтобы наложить дополнительные карты нормалей или высот, и сделать нашу картинку объемнее.

 Выбираем нашего персонажа (Окно SpriteEdtior по клику на на файл персонажа.psb, youtubeIntro). Источник: личный архив автора

Выбираем нашего персонажа (Окно SpriteEdtior по клику на на файл персонажа.psb, youtubeIntro). Источник: личный архив автора

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

Результат — свет знает, как осветить sprite. Высоты и углубления знаем благодаря NormalMap. Источник: личный архив автора
Результат — свет знает, как осветить sprite. Высоты и углубления знаем благодаря NormalMap. Источник: личный архив автора

Результат — свет знает, как осветить sprite. Высоты и углубления знаем благодаря NormalMap. Источник: личный архив автора

Идем дальше: проверяем, распознались ли все элементы в главном окне корректно, и можем переименовать или изменить pivot по необходимости. Теперь нас интересует Skinning Editor.

Окно Skinning Editor. Источник: личный архив автора

Окно Skinning Editor. Источник: личный архив автора

Полезные ссылки о PSD Importer о SkiningEditor. Рекомендую ознакомиться с примерами, если есть желание создать что то отличное от нашего персонажа, и чтобы понять разные стороны инструмента.

Оранжевым цветом на скриншоте подсвечено, какую панель стоит включить. С ее помощью мы правильно выложим наши кости, и она работает как стандартная иерархия объектов в Unity (Hierarchy — главная панель, переставления родительских объектов в дочерние, — прим. авт.).

Советую сразу именовать новосозданную кость в панели Visibility -> Bone (на скриншоте ниже выделено оранжевым).

Финальный результат настройки костей. Источник: личный архив автора

Финальный результат настройки костей. Источник: личный архив автора

Нажимаем AutoGeometry для построения геометрии под каждый спрайт. Это позволяет в тонкой настройке задать нужный Mesh Deformation. Убрав выделение с какого-либо спрайта, жмем AutoWeight.

Маловероятно, что тулза на 100% распознала все верно. Перейдем в детальные настройки. Первое, что нас интересует — какой спрайт и область привязалась к кости. Для этого открываем Bone Influence.

Bone Influence — настройка привязки костей к изображению и его областям. Источник: личный архив автора

Bone Influence — настройка привязки костей к изображению и его областям. Источник: личный архив автора

В нашем случае будет достаточно того, чтобы одна кость управляла только одним спрайтом и всей его областью.

Примечание: есть более продвинутый режим — это, например, когда надо сделать, чтобы плащ был анимирован. Для этого вручную настроена сетка (вкладка Edit Geometry), и заданы несколько костей с областями с помощью инструмента Weight Brush. Но для первичного разбора нам достаточно правильно задать привязки костей к картинкам.

Когда мы уберем лишние кости, увидим, что вся область подсвечивается цветом этой кости. Если что-то не так, перегенерируйте Weight (AutoWeights -> Generate).

Финальный результат настройки. Источник: личный архив автора

Финальный результат настройки. Источник: личный архив автора

В случае правильной настройки костей к областям изображения (у нас же — ко всему слою картинки), переходим к настройке иерархии. На вкладке visibility мы видим финальный результат. Если у тебя было подобное наименование костей, ты легко можешь это проверить.

Примечание: Рекомендую для ног и рук сделать три кости, или позже добавить их в режиме префаба. Так нам будет проще с помощью LimbSolver 2D (из пакета 2D Animation — компонент инверсной кинематики, — прим. авт.) настроить конечности. Не забываем нажать Apply, перекидываем наш префаб в Unity:

Настроенный персонаж исходное состояние. Источник: личный архив автора

Настроенный персонаж исходное состояние. Источник: личный архив автора

Настройка персонажа для анимации с помощью инверсной кинематики

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

Создание родительского объекта для персонажа. Источник: личный архив автора

Создание родительского объекта для персонажа. Источник: личный архив автора

Создаем префаб персонажа. У новой системы префабов Unity (начиная с версии 2018 года, — прим. авт.) есть некоторые особенности. Например, объект, который мы создали из ассета, не будет сохранять изменения. Даже если это исходник, как и любая 3D-модель. Поэтому для сохранения своих трудов рекомендую вкладывать подобные объекты в еще один родительский:

Исходный файл персонажа. Источник: личный архив автора

Исходный файл персонажа. Источник: личный архив автора

Далее добавляем четыре Limb Solver — это будут наши конечности. И один ССD, так как у нас между головой и туловищем всего две кости. Здесь мы можем настроить точнее. Если нет желания заморачиваться, можно просто создать пустой объект (в нашем случае — вместо меча), и сдвинуть его, или вовсе учесть в настройках костей шагом ранее.

Примечание: CCD и FABRIK отличаются точностью и количеством проходов по иерархии. Рекомендую ознакомиться с документацией подробнее.

Добавляем Limb Solver. Источник: личный архив автора

Добавляем Limb Solver. Источник: личный архив автора

Теперь именуем наши вновь созданные объекты, и создаем по одному простому GameObject под каждый. Желательно их тоже назвать, чтобы в дальнейшем не теряться. Устанавливаем Target в каждом созданном Solver — четыре Limb и один CCD.

Устанавливаем Target в дочерние объекты. Источник: личный архив автора

Устанавливаем Target в дочерние объекты. Источник: личный архив автора

Теперь устанавливаем Effector-точку для каждого IK Solver:

ArmL Solver Setup. Источник: личный архив автора
ArmL Solver Setup. Источник: личный архив автора
ArmL Solver Setup. Источник: личный архив автора

ArmL Solver Setup. Источник: личный архив автора

Мы можем задать длину воздействия на потомков (выделено зеленым на скриншоте) до плечей, или в нашем случае до Roota. Когда поднимем наши точки с пола, увидим, что пока не все так гладко.

Результат первичной настройки. Источник: личный архив автора

Результат первичной настройки. Источник: личный архив автора

Здесь мы видим две проблемы. Во-первых, наши суставы смотрят не в ту сторону. Во-вторых, наш управляющий point направляет руки персонажа не туда, куда надо.

Для начала поправим положение рук. Для этого переходим в конечную иерархию в Sword. Наведя курсор между X и значением, появляется альтернативный курсор — <>. Кликаем и понемногу меняем положения так, чтобы наш меч лег в руку. Ту же операцию проводим и для координаты Y при необходимости.

Настройка IK. Источник: личный архив автора

Настройка IK. Источник: личный архив автора

Сделаем так с обеими руками. Если у тебя кости находятся последовательно друг за другом, с этой проблемой ты не столкнешься. Также удостоверимся, что родительский объект не имеет смещения:

Проверка на смещение управляющих точек. Источник: личный архив автора

Проверка на смещение управляющих точек. Источник: личный архив автора

Переходим к суставам. Для этого кликаем на Flip-настройку. Этот инструмент вывернет сустав в нужную сторону. Здесь все зависит от первоначального скелета. В нашей ситуации имеем дело с ногами:

Настройка суставов. Источник: личный архив автора

Настройка суставов. Источник: личный архив автора

Мы получили настроенного персонажа, которым можем управлять с помощью пятью точек. Также нам доступен Root, который не привязан к инверсной кинематике. Сдвигая его, мы можем менять положения тела, а наши IK Solver оставят конечности в той же позиции.

Финальный результат настройки. Источник: личный архив автора

Финальный результат настройки. Источник: личный архив автора

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

В следующей части рассмотрим создание кат-сцены и то, как мы можем скомпозировать управление камерой, эффектами и уже настроенным персонажем в одном таймлайне с помощью Cinemachine Package.

У меня есть персонаж, состоящий из нескольких спрайтов (ноги, торс, голова, руки). У персонажа есть возможность подбирать оружие разных типов.

Каждый тип оружия имеет свою собственную анимацию (спрайт-лист). В идеале я хочу, чтобы оружие не только анимировало себя, но и влияло на анимацию игрока (например, откидывался назад, когда размахивал мечом).

Вот как я собираюсь настроить это прямо сейчас:

Основные вопросы: - Как я могу включить в это прыжки? - Как анимация оружия может контролировать остальную часть тела?

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

1 ответ

Ваш подход противоположен тому, что я бы сделал. Оружие не контролирует персонажа, наоборот. Поэтому я предлагаю настроить анимацию персонажа, чтобы он прыгал нормально, так как у него в руках оружие. Если у вас есть несколько типов оружия (легкое, тяжелое, обычное . ), вы можете настроить анимацию для каждого из них, это, вероятно, просто повлияет на то, как руки держат оружие, и, возможно, на осанку тела. В персонаже, когда вы прыгаете, вы запускаете правильную анимацию для типа оружия, которое вы держите.

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

Как мы все знаем во многих играх разработчикам выбирают для проведения боя пошаговую систему. Такая система пользуется популярностью в пошаговых играх, например, серия игр герои. Я разумеется не буду рассматривать весь механизм работы пошаговой игры, такие моменты как переход от “обычного” режима в режим боя. Все это реализовать будете вы, так как в каждой игре это все выглядит по своему и написать один уникальный скрипт не получится. Хотя, если там будет куча странного кода, то получится, но производительности это не добавит.

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

Этот урок предполагает, что вы знакомы с интерфейсом Unity и базовыми концепциями скриптинга. Дополнительно, вы должны быть знакомы с концепциями, изложенными в первой части этого урока.

Before we begin — level setup

  • Создайте новый проект (новый! не продолжайте старый!).
  • Скачайте проект с необходимыми файлами и откройте его.
  • Добавьте mainLevelMesh и FPC в сцену.

Weapon switching

Rocket Launcher

Launcher

Rocket


// The reference to the explosion prefab
var explosion : GameObject;
var timeOut = 3.0;

// Kill the rocket after a while automatically
function Start ()
Invoke("Kill", timeOut);
>
Сначала функция Kill ищет системы частиц в иерархии дочерних объектов и выключает их (параметр emit). Затем, открепляет все дочерние объекты от объекта (ракеты в данном случае) и удаляет ракету.

function OnCollisionEnter (collision : Collision)
// Instantiate explosion at the impact point and rotate the explosion
// so that the y-axis faces along the surface normal
var contact : ContactPoint = collision.contacts[0];
var rotation = Quaternion.FromToRotation(Vector3.up, contact.normal);
Instantiate (explosion, contact.point, rotation);

// And kill our selves
Kill ();
>

function Kill ()
// Stop emitting particles in any children
var emitter : ParticleEmitter= GetComponentInChildren(ParticleEmitter);
if (emitter)
emitter.emit = false;

  • Выберите объект RocketLauncher.
  • Перетащите префаб Rocket из WeaponPrefabs в слот параметра Projectile.
  • Запустите игру, тестируйте.

Explosions

  • Перетащите префаб /Standard Assets/Particles/Small explosion на переменную Explosion в скрипте Rocket в префабе Rocket.

function Start ()
var explosionPosition = transform.position;
var colliders : Collider[] = Physics.OverlapSphere (explosionPosition, explosionRadius);
Это возвращает массив коллайдеров, которые попали в сферу.
for (var hit in colliders)
if (!hit)
continue;

if (hit.rigidbody)
hit.rigidbody.AddExplosionForce(
explosionPower, explosionPosition, explosionRadius, 3.0);
Это применяет силу ко всем rigidbodies в пределах радиуса взрывы (сферы).
В принципе, взрыв выглядит неплохо.
var closestPoint = hit.rigidbody.ClosestPointOnBounds(explosionPosition);
var distance = Vector3.Distance(closestPoint, explosionPosition);

// stop emitting ?
if (particleEmitter)
particleEmitter.emit = true;
yield WaitForSeconds(0.5);
particleEmitter.emit = false;
>

  • Добавьте скрипт Explosion-Simple.js к префабу Small explosion.
  • explosionPower — величина силы, с которой взрыв будет передвигать объекты.
  • explosionDamage — величина повреждений.
  • explosionRadius — радиус действия взрыва.
  • Запустите игру.

Machine Gun

  • Создайте пустой объект и назовите его MachineGun. Добавьте его как дочерний объект в объект Weapons.
  • Добавьте меш /Objects/weapons/machineGun в пустой объект MachineGun.
  • Прикрепите скрипт MachineGun.js к объекту MachineGun
  • Поместите muzzle_flash (дочерний объект в machineGun) в переменную Muzzle Flash компонента-скрипта Machine Gun в объекте MachineGun.

function Start ()
hitParticles = GetComponentInChildren(ParticleEmitter);

// Play sound
if (audio)
audio.loop = false;
>
>
>
>
Функция LateUpdate автоматически вызывается после вызова функции Update. Заметьте, что функция Update вызывается в скрипте PlayWeapons.js, который прикреплён к объекту Weapons (родитель объекта MachineGun). В основном, функция LateUpdate будет использоваться тогда, когда нужно реагировать на произошедшее внутри функции Update. В данном случае, если игрок стреляет в функции Update, то в функции LateUp­date будет применяться вспышка (muzzle flash).
function Fire ()
if (bulletsLeft == 0)
return;

// If there is more than one bullet between the last and this frame
// Reset the nextFireTime
if (Time.time - fireRate > nextFireTime)
nextFireTime = Time.time - Time.deltaTime;

// Keep firing until we used up the fire time
while( nextFireTime 0)
clips-- ;
bulletsLeft = bulletsPerClip;
>
>

function GetBulletsLeft ()
return bulletsLeft;
>
Функция Reload перезаряжает оружие. Продолжительность перезарядки — публичная переменная.

Configuring the particle emitter

  • Перетащите префаб /StandardAssets/Particles/Sparks на machineGun в Hierarchy, сделав его дочерним.
  • Это всё. Запустите игру. Оружие переключается клавишами 1 и 2.

Hit Points

Скрипты Explosion.js и MachineGun.js уже показали, как рассчитывать величину повреждений от снарядов (ракеты и пули) и посылать эти значения в повреждаемые объекты. Однако, объекты не знают, как получить (принять) эти значения.
Объекты отслеживают то, насколько они здоровы, с помощью переменной hitPoints. Каждый объект инициализируется со своим значением. Каждый, который объект должен получать повреждения, должен иметь функцию ApplyDamage() (заметьте, что функция вызывается из скриптов Explosion.js и MachineGun.js) Эта функция уменьшает количество HP в игровом объекте и вызывает функции, работающие с объектом, HP которого упали до нуля (обычно, это смерть).
Далее мы продемонстрируем, как использовать hitPoints и ApplyDamage()

Exploding Barrels

Рассматриваемый нами код является типовым и может использовать во многих ситуациях.
Вот полный код DamageReceiver.js:
var hitPoints = 100.0;
var detonationDelay = 0.0;
var explosion : Transform;
var deadReplacement : Rigidbody;

Skybox

  • Edit→Render Settings. Перетащите /Materials/skyBoxTest в параметр Skybox Material.

Prerequisites

Этот урок предполагает, что вы знакомы с интерфейсом Unity и базовыми концепциями скриптинга. Дополнительно, вы должны быть знакомы с концепциями, изложенными в первых двух частях этого урока.

Setting up

  • Откройте предыдущий проект (созданный в части 2).

Waypoints

Robot AI

Robot Damage

  • Прикрепите скрипт CharacterDamage к префабу Robot.
  • Запустите игру и стреляйте по роботу. Он умрёт и исчезнет, ага.

Ragdolls

  • Сначала создайте новую сцену. Мы настроим регдолл здесь. Не забудьте сохранить текущую сцену.
  • Создайте куб больших размеров. Он будет служить платформой для робота. Перетащите робота в сцену и расположите на кубе.
  • Удалите компонент Animation. Это важно, иначе анимация будет конфиликтовать с физикой.
  • Используйте мастера создания регдолла: Gameobject→CreateOther→Ragdoll
  • Сначала, rootHandle назначаем на root.
  • Установите Total Mass на 4.

Upper body / Arms

Using the Ragdoll

  • Откройте исходную сцену, выберите робота в Hierarchy. Перетащите префаб Robot-Ragdoll в переменную Dead Replacement скрипта-компонента Character Damage.
  • Запустите игру и стреляйте по роботу. Должен упасть.

Sound

Machine gun

Rocket Launcher

  • Выберите префаб Rocket.
  • Добавьте компонент Audio Source.
  • Перетащите аудиофайл RocketLauncherFire на параметр Audio Clip.
  • Настройте RolloffFactor (0.5 должно быть достаточно).

GUI (Графический Интерфейс Пользователя) предоставляет пользователю обратную связь и информирует его о текущей ситуации. Стандартные элементы GUI: количество патронов, здоровье, цели миссии и т. п.
В этой игре мы сделаем три элемента GUI.

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