Создание и уничтожение игровых объектов (GameObjects)
Некоторые игры имеют постоянное количество объектов на сцене, однако обычно персонажи, сокровища и другие объекты создаются и удаляются во время игры. В Unity, игровой объект (GameObject) может быть создан используя функцию Instantiate, которая делает копию существующего объекта:-
public GameObject enemy; void Start() < for (int i = 0; i < 5; i++) < Instantiate(enemy); >>
Заметьте, что объект с которого берется копия не обязан присутствовать на сцене. Гораздо чаще используется префаб, который был перетащен на открытую переменную (public variable) из файлов проекта в панели Project. Также, копируя игровой объект (GameObject), вы копируете все компоненты оригинального объекта.
Также есть функция Destroy, которая уничтожит объект после того, как загрузка кадра будет завершена или опционально после короткой паузы:-
void OnCollisionEnter(Collision otherObj) < if (otherObj.gameObject.tag == "Missile") < Destroy(gameObject,.5f); >>
Заметьте что функция Destroy может уничтожать отдельные компоненты без влияния на сам объект. Частая ошибка — писать что-то вроде этого:-
Destroy(this);
…что на самом деле уничтожит только вызывающий скриптовый компонент, вместо того, чтобы уничтожить игровой объект, к которому присоединен этот скрипт.
Как создать спавн объектов в Unity
Приветствую начинающих разработчиков! В данной статье мы научимся спавнить объекты на игровой сцене на примере 2D игры. Хотя он подойдёт и для 3д, но с минимальными изменениями в коде. Долго затягивать не будем, а приступим сразу к делу.
Для начала с помощью окна Hierarchy создадим пустой игровой объект(Create Empty), и назовём его SpawnArea. Этот объект будет являться нашим спавнером. Так же создайте префаб того объекта, который будет спавниться. Я создал свой префаб на основе обычного круглого 2д объекта (2D Object — Sprites — Circle). Назвал данный префаб Circle.
Спавнер вместе с префабом готов! Но чтобы этот спавнер работал, необходимо написать скрипт. С помощью окна Project создадим C# скрипт с названием Spawner, и заранее присвойте его нашему объекту с названием SpawnArea. В скрипт пропишите следующие строчки кода:
using UnityEngine; public class Spawner : MonoBehaviour < public GameObject enemyPrefab; public float timeSpawn = 2f; private float timer; private void Start() < timer = timeSpawn; >private void Update() < timer -= Time.deltaTime; if (timer > >
Давайте вкратце разберём код:
- В строке #5 мы создали переменную enemyPrefab, в которой будет храниться ссылка на наш префаб, который будет спавниться.
- В строках #7-8 мы создали две переменные отвечающие за время. В переменной timeSpawn хранится информация о том, сколько необходимо времени, для создания объекта на сцене. А в timer будет хранится сам таймер, по истечении которого будет создаваться объект на игровой сцене. Чуть позже вы поймёте разницу.
- В методе Start() мы в переменную timer заносим значение из timeSpawn.
- В методе Update() мы каждый кадр уменьшаем время нашего таймера timer, и как только оно закончится, то значение timer обновляется, а на игровой сцене, с помощью метода Instantiate() создаётся новый объект.
И в завершении необходимо настроить наш скрипт в окне Inspector:
- В поле Enemy Prefab перетащите префаб Вашего объекта Circle.
- В поле Time Spawn укажите время спавна для таймера. Я указал значение 2.
Готово! На этом этапе можете запустить свой проект, и убедиться, что всё работает успешно! Каждые 2 секунды происходит создание нового игрового объекта.
Спавнер созданный выше хорошо работает, но предлагаю его немного усовершенствовать, поскольку мне не нравятся в нём две вещи. Во-первых, все объекты создаются в одной точке, а хотелось бы, чтобы они создавались в случайной области в пределах определённого радиуса. А во-вторых, хотелось бы, чтобы создание объектов не производилось в тех случаях, когда в игре уже присутствует 10 объектов.
Предлагаю чуть чуть переписать наш код следующим образом:
using UnityEngine; public class Spawner : MonoBehaviour < public GameObject enemyPrefab; public int maxEnemy = 5; public float timeSpawn = 2f; private float timer; public float distance = 3; private void Start() < timer = timeSpawn; >private void Update() < timer -= Time.deltaTime; if (timer > > >
Что же мы тут добавили? В строке #6 мы добавили переменную maxEnemy, которая отвечает за максимальное количество созданных объектов на игровой сцене. А в строке #11 в переменной distance храниться множитель для нашего радиуса спавнера, в пределах которого будут создаваться объекты. А сам радиус прописывается в строке #26 через Random.insideUnitCircle.
В строке #24 с помощью свойства childCount мы проверяем, сколько у нас имеется созданных объектов. И если их число меньше 10, то происходит создание нового объекта, иначе — ничего не делать.
Наш скрипт готов! Теперь запустим его, и увидим следующую картину. Каждые 2 секунды в нашем проекте создаётся по одному объекту, в случайной точке, радиусом в 3, от нашего спавнера. И как только было создано 10 объектов, спавнер прекращает свою работу.
Но и этот спавн можно усовершенствовать. Мы можем спавнить не один и тот же объект, а разные объекты, которые будут спавниться случайным образом. Но это уже совсем другая история. О том, как это можно реализовать, можете прочитать наш отдельный гайд, под названием «Создаём рандомный спавн объектов».
На этом наш гайд подошёл к концу. Если остались вопросы, задавайте их в комментариях. А так же не забывайте ставить свои лайки.
Как постоянно спавнить объекты в юнити 3д?
Потому что yield return new WaitForSeconds(0.5f); должен участвовать только в корутинах. А в голом апдейте надо запоминать время (класс Time ) нажатия и проверять когда уже прошло нужное количество секунд.
Ответ написан 15 июл. 2023
Нравится 1 2 комментария
Oleg_KeyKode @Oleg_KeyKode Автор вопроса
А если я пропишу yield return new WaitForSeconds(0.5f); в другом методе, и буду вызывать его в апдейте?
Oleg_KeyKode, Напиши, зачем спрашивать у меня разрешение
node.js, c#, UI
Как уже и сказал freeExec yield return используется в Coroutines, если не знаешь что это, то вот тебе доки юньки (тут всё ясно и подробно описано)
https://docs.unity3d.com/Manual/Coroutines.html
p.s: есть переводчик, переведи английский и поймёшь на 100%
p.p.s:если нужен пример кода, то там тоже всё есть и довольно подробно всё показано
удачки
Создаём рандомный спавн объектов
Бывают случаи, когда при определённых условиях нам необходимо создать случайный объект на игровой сцене. Например, при нажатии на кнопку, или при уничтожении ящика, из него должно выпасть случайный предмет. Давайте же это сейчас реализуем.
Для начала в окне Hierarchy создадим пустой объект(Create Empty), и назовём его SpawnArea. Этот объект будет являться нашим спавнером, и именно в нём будет спавниться случайный объект. Так же необходимо создать несколько префабов для спавна. У меня всего три префаба: арбуз, груша и яблоко.
Спавнер вместе с прифабами готов. Осталось написать скрипт. Создаём C# скрипт с названием Spawner, и заранее присвойте его к объекту SpawnArea. Впишите в него следующий код:
using UnityEngine; public class Spawner : MonoBehaviour < public GameObject[] obj; private void Start() < Spawn(); >public void Spawn() < int random = Random.Range(0, obj.Length - 1); Instantiate(obj[random], transform); >>
Предлагаю вкратце разобрать этот код:
- В строке #5 мы создали массив объектов для спавна. Там будут хранится ссылки на префабы моего арбуза, яблока и груши.
- Так же мы создали метод Spawn() в котором будет генерироваться случайное число от нуля, до длины нашего массива — 1. В нашем случае получается от 0 до 2.
- Ну а запускать метод Spawn() мы будем в методе Start(), который сработает сразу же при старте игры.
И остался последний штрих. Необходимо в окне Inspector для нашего скрипта Spawner в поле Obj перетащить все наши префабы.
Можете запустить свой проект, и сразу же при старте игры на игровой сцене появится случайный объект.
Хочу обратить ваше внимание, что запуск Spawn() в методе Start() был всего лишь демонстративным. Его мы можете запускать когда угодно, например, при клике на определённую кнопку, или сразу же после уничтожения того самого ящика, или врага.
Бывают случаи, когда нам необходимо создавать объекты не единожды, а многократно, например, каждые 5 секунд, и не в одной точке пространства, а в случайных, то советую посмотреть мой предыдущий гайд, который называется Как создать спавн объектов в Unity.
А на этом всё. Если есть вопросы — пишите в комментариях, и не забывайте о лайках 🙂