Как сделать урон в unity 3d

Обновлено: 07.07.2024

Этот урок предполагает, что вы знакомы с интерфейсом 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.

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

В плеере есть жесткое тело2D. На игроке и поражающих объектах есть Box Collider 2D.

1 ответ

Убедитесь, что в проигрывателях Collider включен isTrigger .

attackDamage является общедоступным -> устанавливается в инспекторе. Убедитесь, что это не 0 .

Вы могли бы использовать

чтобы автоматически зафиксировать значение в инспекторе.

Предположение, но я бы сказал, что ваш Collider может не быть в GameObject player , но, вероятно, в одном из его дочерних объектов => условие col.gameObject == player не верно.

Вместо ссылок GameObject лучше сравните ссылку PlayerHealth (поскольку существует только одна) ссылка, например

Я не знаю, что еще должно произойти на TakeDamage , но значение damaged сбрасывается в Update , поэтому сразу после того, как оно было установлено Trigger , потому что события физики, такие как OnTriggerEnter выполняются до Update (см. Порядок выполнения).

Вы также можете использовать

Если этот компонент существует только один раз в вашей сцене.

Или, чтобы быть более гибким (имея несколько игроков), все, что вам нужно сделать, это изменить методы OnTriggerEnter2D и Attack на










public class bulletdamage : MonoBehaviour <
public enemy test;
public int Damagepoint = 25;

void OnCollisionEnter(Collision collision)
<
Damage();
>

void Damage()
<
test.Health -= Damagepoint;
>

// Use this for initialization
void Start ()

// Update is called once per frame
void Update ()

]
и такой скрипт на врага:
[/code
using UnityEngine;
using System.Collections;

public class enemy : MonoBehaviour <
public int Health = 100;

public class bulletdamage : MonoBehaviour <
public enemy test;
public int Damagepoint = 25;

void OnCollisionEnter(Collision collision)
<
Damage();
>

void Damage()
<
test.Health -= Damagepoint;
>

// Use this for initialization
void Start ()

// Update is called once per frame
void Update ()

]
и такой скрипт на врага:
[/code
using UnityEngine;
using System.Collections;

public class enemy : MonoBehaviour <
public int Health = 100;

// Use this for initialization
void Start () <
if(Health Автор - displas
Дата добавления - 27 Июл 2014 в 15:16


скрипт на врага
public void Damage(int dmg)

скрипт на врага
public void Damage(int dmg) < Health -= dmg; >Автор - Hunjeth
Дата добавления - 27 Июл 2014 в 16:21


скрипт на пули
void OnCollisionEnter(Collision collision) <
//collision.gameObject.SendMessage("Damage", Damagepoint, SendMessageOptions.DontRequireReceiver);
collision.gameObject.SendMessage("Damage", Damagepoint);
>

скрипт на врага
public void Damage(int dmg)

using UnityEngine;
using System.Collections;

public class enemy : MonoBehaviour <
public int Health = 100;
public void Damage(int dmg)

скрипт на пули
void OnCollisionEnter(Collision collision) <
//collision.gameObject.SendMessage("Damage", Damagepoint, SendMessageOptions.DontRequireReceiver);
collision.gameObject.SendMessage("Damage", Damagepoint);
>

скрипт на врага
public void Damage(int dmg)

using UnityEngine;
using System.Collections;

public class enemy : MonoBehaviour <
public int Health = 100;
public void Damage(int dmg)

// Use this for initialization
void Start () <
if(Health Автор - displas
Дата добавления - 27 Июл 2014 в 20:36

[Unity3D] Отображение значения урона при разработке игры Unity3D

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

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



Поскольку он основан на методе OnGUI (), я считаю, что все должны быть хорошо знакомы с ним. Итак, мы даем код напрямую:

В приведенном выше коде нам нужно понять следующие моменты:

1. Получите координаты положения в соответствии с компонентом Transform и преобразуйте эти координаты в координаты экрана и координаты GUI.

2. Четыре общие системы координат в Unity3D:

• Мировые координаты: координаты объектов в сцене. Используйте transform.position, чтобы получить его.

  b, координаты экрана: определены в пикселях. Принимая нижний левый угол экрана за точку (0, 0), а верхний правый угол за (Screen.width, Screen.height), положение Z измеряется в мировых единицах измерения камеры. Например, Input.mousePosition - это координаты экрана.

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

Координаты GUI: система координат использует верхний левый угол экрана как точку (0.0), а нижний правый угол как (Screen.width.Screen.height).

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

Все в порядке. Ниже мы свяжем этот скрипт с пустым телом игры. И сделано в пресете, в следующем демонстрационном примере. Мы будем использовать этот пресет.



Как показано на рисунке, мы надеемся достичь, когда персонаж атакует красную капсулу. На игровой сцене отображается значение ущерба, нанесенного игроком корпусу капсулы. Как это сделать? Сначала мы можем добавить коллайдер к модели и корпусу капсулы и проверить IsTrigger, чтобы сделать его триггером. Мы устанавливаем их теги в Player и Enemy соответственно.

Далее напишите сценарий для врага:

Здесь мы устанавливаем величину урона игрока противнику от 20 до 40. После выполнения программы мы получим следующие результаты:

Поскольку здесь блоггер использует неточные коллизии, персонаж сталкивается с телом капсулы в начале программы, а метод OnTrigger () может зафиксировать коллизию только тогда, когда коллизия начинается. Так что здесь только показывает значение урона один раз.

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

Пока что эта проблема успешно решена.

Некоторые друзья могут спросить: почему эффект повреждения, отображаемый в играх других людей, выглядит настолько ослепительно, но ваша программа может отображать только обычный текст? Для этой проблемы мы даем две идеи здесь, оставьте это для каждого, чтобы исследовать.

Первый способ - создать GUISkin в проекте, а затем добавить переменную-член GUIStyle mStyle в сценарий DamagePopup. Через эту переменную мы можем ссылаться на GUISkin, созданный в проекте.

Таким образом, мы можем определить общий стиль GUI. В настоящее время мы изменим метод в OnGUI на:

Чтобы мы могли достичь текстового эффекта, который мы определили. Другой метод - использовать текстуры, то есть сначала подготовить цифровые изображения от 0 до 9, а затем отдельно вырезать числа на каждой цифре значения Value и рисовать текстуры в соответствии с результатами перехвата, чтобы они могли достигать эффектов, определенных нами. Все в порядке. Это все для сегодняшнего контента. Спасибо за ваш интерес к моему блогу, и я надеюсь, что вам понравится сегодняшний контент.

Ежедневные Притчи: Живите более элегантно, другие не могут вас одолеть, внутренняя сила - настоящая сила.

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

Для начала рассмотрим все в теории, а потом уже возьмемся за реализацию и тестирование.

Теория

Физическое тело в виде снаряда

Итак, у нас есть задача бросить камень, надеюсь не в меня) Для этого делается следующее:

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

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

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

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

Как же быть? Для таких целей обычно используют рейкаст

Рейкаст для реализации выстрела

В простейшем случае работает это таким образом:

  • Мы выпускаем луч в нужном направлении
  • Определяем куда он попадет
  • рисуем эффект попадания или делаем что то еще

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

Пример как пуля пролетает препятствие

Пример как пуля пролетает препятствие

Как решить данную проблему?

Можно после получения конечной точки пустить еще один луч и проверить соприкосновения еще раз, это не совсем правильно но не так затратно по ресурсам.

Можно запустить симуляцию всего полета "на паузе". Расчет требует времени и соответственно ресурсов, однако точно просчитает полет пули. Это почти так же как и в варианте с физическим объектом, но расчет ведется отдельно от текущего времени и выдается только результат.

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

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

Практика

Физический снаряд

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

Тестовый стенд

Тестовый стенд

Стрелять будем в точку, без поворота камеры.

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

Первый выстрел Последствия

Путь луча

Принцип описан выше, сцена та же самая, код чуть ниже. Для Визуализации я буду создавать "пулю" в точке соприкосновения луча и объекта. В реальном проекте, там нужно оставлять следы от пуль, искры, осколки, все что захотите.

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

Так же можно добавить поведение оружия. Отдача, точность, разброс и тд. Тут уже полностью от ваших хотелок.

Итоги

В данной статье я привел лишь примеры того как можно сделать выстрелы в unity. Надеюсь она вам поможет определиться как действовать дальше и у вас получиться хорошая стрелялка =)

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