unity создать пустой объект в скрипте
Создание объектов
Некоторые игры имеют постоянное количество объектов на сцене, однако обычно персонажи, пули, сокровища и другие объекты создаются и удаляются во время игры. В Unity, игровой объект (GameObject) может быть создан через функцию Instantiate, которая делает копию существующего объекта. Объект, который мы будем клонировать, должен быть prefab’ом и сохранен в папке Resources.
Сейчас ты напишешь пару скриптов, с помощью которых можно научиться создавать (spawn’инть) игровые объекты, например, для того, чтобы реализовать механику вот такой ловушки:
Ловушка
Подготовка
Тебе понадобятся четыре игровых объекта и скрипт, с которым ты уже знаком:
Stone
По нашему плану нам понадобятся камни, которые будут создаваться над головой Игрока. Выбери 3D-модель, которая тебе понравилась, добавь ей компоненты Rigidbody и два коллайдера: Capsule и Box. Box коллайдер должен быть чуть больше, чем Capsule, а также иметь включенным свойство Trigger.
После этого добавь этому игровому объекту скрипт OnTriggerSceneLoader и укажи в его свойствах название текущей сцены (а еще не забудь добавить ее в Build Settings).
Stone и его компоненты
Не забудь сохранить объект Stone, как prefab, в папке Resources!
Программирование
Тебе понадобятся два новых скрипта, чтобы все работало как нужно: Spawner.cs и TrapSwitch.cs
Spawner
Как мы уже говорили, в Unity есть функция Instantiate, которая делает копию существующего объекта:
В нашем случаем наш объект будет физическим, так что ты можешь сразу объявить Rigidbody, также понадобится переменная, в которой ты будешь указывать необходимое количество клонов:
Теперь нужно написать публичный метод, который ты будешь вызывать скриптом TrapSwitch.cs, стандартные методы Update() и Start() нам не понадобятся, так что их можно удалить:
Чтобы выполнить функцию Instantiate несколько раз, используй цикл, например, do while:
Технически, скрипт готов, но, если оставить все как есть, то во время выполнения метода Spawn(), практически, одновременно в одной точке появятся все amount (число) клоны. Из-за того, что наши клоны содержат в себе компоненты Rigidbody и коллайдер, клоны просто разлетятся в разные стороны, что выглядит не очень. При этом, шанс, что хотя бы один клон-камень попадет в Игрока будет очень низок. Поэтому добавь немного рандома и сделай так, чтобы каждый следующий камень создавался выше предыдущего на i:
Теперь все работает как нужно. Продолжим.
TrapSwitch
TrapSwitch будет размещен на объекте с триггером, когда Игрок будет его касаться, TrapSwitch будет запускать метод Spawn() у объекта Spawner. Напомним про коллайдеры и триггеры:
Сейчас тебе понадобиться метод OnTriggerEnter. Он выполняется, когда объект только вошел в зону триггера один раз. Создай такой скрипт:
Ты собираешься взаимодействовать с двумя игровыми объектами и объектом Spawner. Их нужно объявить:
Теперь необходимо убедиться, что объект, который войдет в триггер является Игроком. Это можно сделать, используя тег, как в OnTriggerSceneLoader:
Теперь последовательно напиши все необходимые команды внутрь условия: удаление (уничтожение) объекта TrapOn, включение объекта TrapOff, выполнение метода Spawn() и удаление (уничтожения) себя.
Все скрипты написаны. Поздравляем! Осталось правильно разместить все объекты на сцене и не забыть указать им друг на друга.
MVC в Unity со Scriptable Objects. Часть 2
Продолжение цикла статей от Cem Ugur Karacam (часть 1 можно прочитать здесь).
В этот раз мы начнем с того, что создадим несколько представлений для отображения объекта инвентаря и панель информации для отображения параметров объекта. Этакий примитивный инвентарь. Затем сосредоточимся на окне инвентаря, а окно статистики закончим в следующей части.
Давайте посмотрим, из чего будет состоять наша работа. Нам предстоит:
Мы будем использовать объекты Unity UI. Создадим пустую канву (правый клик в окне иерархии → UI → Canvas).
Далее создадим две панели — информацию о предмете и инвентарь.
Также создадим объект для фона, назовем его BG и назначим на него компонент Vertical Layout.
Теперь дочерние объекты фона будут выравниваться по вертикали.
Давайте создадим внутри BG панель.
Установим в компоненте RectTransform только высоту панели — 300, а ширину оставим автоматической, под управлением компонента Vertical Layout. Вот мои настройки для объекта BG:
Теперь продублируем панель и поставим высоту 440.
Затем дадим панелям правильные имена.
Должно выглядеть так:
Рассказ о работе над объектом InfoPanel продолжится в следующей части.
Давайте подготовим представление для предмета инвентаря и сохраним как префаб. Создадим кнопку внутри панели. Чтобы получить правильное отображение предметов в инвентаре, добавим удобный компонент Grid Layout Group на объект InventoryPanel.
Теперь каждый дочерний объект панели инвентаря будет размещен на экране согласно настройкам сетки в компоненте Grid Layout Group. Вернемся к кнопке.
Кнопка работает неправильно, потому что мы еще не настроили сетку. Пока добавим объект Image к кнопке как дочерний для иконки предмета и снимем флаг Raycast Target с компонента Image, чтобы нажатие на картинку не вызывало нажатия на кнопку.
Теперь скопируем кнопку несколько раз. Четырех копий будет для этого урока достаточно. Вот как должно все выглядеть:
Прежде чем двигаться дальше, мы должны сделать один скрипт для представления предмета. Он будет отвечать за хранение информации о самом предмете инвентаря и реагировать на событие клика по кнопке (пока мы ограничимся выводом в консоль командой Debug.Log).
Создадим новый скрипт и назовем его ItemView.
ItemView отвечает за хранение данных, визуальное представление, обработку нажатий и начальное состояние перед загрузкой данных.
Создадим метод для задания исходного состояния.
Думаю, для нашего проекта потребуется несколько иконок. Я нашел бесплатный комплект на Asset Store. Давайте добавим его в проект.
Теперь можно добавить переменную, которая будет хранить иконку для предмета внутри класса ItemData.
Теперь в ItemView мы можем добавить иконку к представлению.
Добавим скрипт к кнопке в сцене и переименуем объект с кнопкой в Item. После этого назначим в поле ItemIcon объект ImageIcon.
Удалим остальные три кнопки, поскольку они нужны были для настройки сетки, и сохраним объект Item как префаб, перетащив его в окно проекта.
Представление почти готово. Нам нужно 4 предмета, чтобы наполнить инвентарь. Создадим и назначим иконки на модели, которые сделали на предыдущем уроке.
Готово. Теперь создадим скрипт ItemViewController.
Итак, у нас есть ссылка на инвентарь, который хранит ItemData, созданные в папке проекта, ссылку на InventoryPanel, чтобы создавать представления как дочерние объекты этой панели, и ссылку на префаб, в котором лежит само представление предмета.
Теперь в методе Start создадим экземпляр представления предмета и вызовем метод InitItem, чтобы заполнить данные представления данными из модели для каждого элемента инвентаря.
Ну и, наконец, создадим пустой объект в сцене, прикрепим к нему скрипт контроллера и назначим ссылки на требуемые объекты в сцене.
Убедитесь, что в инвентаре все предметы назначены.
Мы сделали довольно много. Теперь посмотрим, как все работает.
Предметы созданы, но я забыл удалить с кнопки объект Text. В Unity кнопки по умолчанию создаются с текстом. Откройте префаб, который мы сохранили в проекте, и удалите объект Text. Затем сохраните префаб и вернитесь к сцене.
Теперь протестируем еще раз.
Поздравляю, все работает.
В следующей части мы займемся панелью информации.
Unity3d script basics
Предисловие
Благодарности
В первую очередь хочу сказать огромное спасибо автору написавшему статью Unity — бесплатный кроссплатформенный 3D движок (и браузерный тоже), и урок Unity3D для начинающих — Туториал 1, статьи очень хорошие, но вот продолжения нету уже довольно долго, в связи с этим я хотел бы помочь автору данных статей просвящать хабралюдей на тему Unity и я думаю он будет не против если я напишу апгрейд его урока.
Резюме
Я долго думал с чего начать и в итоге решил – начать с начала. То есть, с чего начинается большинство игр? Нет не правильно не с заставок и логотипов студии производителя, а с главного меню! В этом уроке я подробно расскажу об основных элементах игрового GUI, о том как загружать сцены из скрипта, а также о том как заставить различные скрипты взаимодействовать друг с другом. В этом уроке мы создадим главное меню для «шутера» созданного в уроке: Unity3D для начинающих — Туториал 1, также я расскажу что всетаки делал скрипт в том уроке, мы немного изменим его и научимся настраивать его во время игры, прямо из нашего игрового меню.
1. Labels и GUIStyle
Мы видим что файл скрипта у нас не совсем пустой, в нем находится функция Update, про неё я расскажу позже, пока что удалим её и напишем следующее:
Сохраним изменения и нажимаем Play.
Видим сверху, не совсем по центру, почти незаметное слово Welcom, написанное черным шрифтом:
Но что такое? Там должно быть слово Welcome!
На самом деле последняя буква потерялась потому что мы объявили ширину квадрата в котором написан текст недостаточной для того чтобы влезло все слово.
Но давайте обо всем по порядку, выключаем Play mode.
Нажмите на Play и полюбуйтесь на результат:
Я не буду описывать за что какая настройка отвечает, ибо урок и без того довольно длинный, попробуйте поиграть с ними, поменять цвет и размер шрифта, наложить текстуру, все довольно просто и интуитивно.
Лирическое отступление Begin
Стандартный редактор:
Лирическое отступление End
2. Buttons и GUISkin
Нажимаем Play, результат должен быть следующий:
Перейдем на наш Menu Skin во вкладке Project и чуть увеличим размер шрифта наших кнопок, тоесть разворачиваем поле Buttons и ставим Font Size равным 16, все это можно делать не выходя из Game mode и при выходе из него изменения сохранятся, так как мы меняем свойства префаба.
3. Меню Options и Sliders
Нет! Не надо! У нас же есть наш замечательный GUISkin по имени Menu Skin. Не выходя из Play mode заходим в него, разворачиваем поле Label, в опции Text Clipping выбираем значение Overflow и убираем галочку напротив Word Wrap, вуаля, все встало на свои места, выходим из Game mode.
4. Play Game and Quit
5. DontDestroyOnLoad и дригие нехорошие слова
Но вот получилась какая незадача. Для того чтобы получить нужные нам данные из скрипта объекта Menu and settings он должен находиться в одной сцене с нашим объектом Player, и как многие уже могли заметить, при нажатии нашей кнопки Play Game все объекты из сцены Menu Scene уничтожаются и во вкладке Hierarchy у нас появляются объекты из второй сцены (Test Scene).
Победить этот недуг нам поможет функция DontDestroyOnLoad(). Её достаточно вызвать один раз в функции Awake() которая вызывается при инициализации скрипта, это своеобразный конструктор для него.
Добавим в скрипт MainMenu следующую функцию:
Войдем в Play mode и нажмем на Play Game. Круто! Меню не исчезло и накладывается у нас теперь поверх всего, это означает что объект Menu and settings не уничтожился, а так же это означает его присутствие во вкладке Hierarchy.
Но меню же теперь постоянно видно! Не порядок и с этим надо бороться, а следовательно модифицируем скрипт (это последний раз):
6. Получаем настройки
Unity3d. Уроки от Unity 3D Student (B04-B08)
Предыдущие уроки вы можете найти в соответствующем топике.
Теперь в каждом посте в скобках (в конце) будут указываться номера уроков. Буква в начале номера обозначает раздел (B-Beginner, I — Intermediate).
PS: Если вы не проходили предыдущие уроки, очень рекомендую их пройти, т.к. последующие изредка на них ссылаются.
Базовый Урок 04 — Уничтожение объектов
В уроке рассказывается как удалять объекты со сцены, использую команду Destroy (уничтожить).
Создайте пустую сцену и добавьте в нее сферу (GameObject->Create Other->Sphere) и куб (GameObject->Create Other->Cube). Куб назовем “Box”. Расположите объекты как показано на рисунке ниже.
Добавьте C#-Скрипт (Project View->Create->C# Script) и назовите его Destroyer. Как уже говорилось, при создании C#-скрипта Unity создает некий каркас, состоящий из подключенных библиотек и основного класса (используемого скриптом) с методами Start() и Update(). В Базовом Уроке 02 (основы ввода) использовался метод Update(), который вызывается каждый кадр. В данном случае мы воспользуемся методом Start(), который выполняется сразу после загрузки сцены. Добавим в тело метода Start() функцию Destroy() и передадим в нее gameObject, указав таким образом, что скрипт должен уничтожить объект, компонентом которого он является:
Добавим скрипт к сфере. Сделать это можно несколькими путями. Перетащив скрипт из Project View на сферу в Scene View.
Или на имя объекта в Hierarchy.
Так же можно выбрать сферу и добавить скрипт через меню компонентов (Component->Scripts->Destroyer) или просто перетащив скрипт в Inspector View выбранного объекта.
Снова выберите сферу и убедитесь, что среди компонентов присутствует ваш скрипт.
Нажмите на Play и вы увидите, что сразу после загрузки сцены сфера исчезает.
Давайте теперь попробуем уничтожить другой объект. Для этого нам понадобится статический метод Find класса GameObject. Заменим код в методе Start() следующим:
Примечание от автора перевода: Обратите внимание, что во втором случае мы передаем значение, вызывая статическую функцию, поэтому пишем имя класса (GameObject — с большой буквы), в то время как в первом мы передаем объект этого класса (gameObject — с маленькой буквы). В противном случае компилятор выдаст ошибку:
error CS0176: Static member `UnityEngine.GameObject.Find(string)’ cannot be accessed with an instance reference, qualify it with a type name instead
что переводится как:
“статический член UnityEngine.GameObject.Find(string) не может быть доступен по ссылки экземпляра (класса), вместо этого определите (вызовите) его с именем типа.”
Сохраним изменения в коде скрипта. Скрипт не требуется убирать со сферы и добавлять к нашему кубу, т.к. назависимо от того, к какому объекту он теперь прикреплен, скрипт будет искать любой объект (на сцене) с именем Box. Нажмем Play и увидим как теперь сфера остается в сцене, а куб пропадает.
Что делать, если нам требуется уничтожить объект не сразу, а спустя какое-то время? Это можно сделать передав значение во 2ой параметр функции Destroy:
Нажмите Play и убедитесь, что куб изчезает через 3и секунды после того, как сцена целиком загрузится.
Дополнительные материалы:
Базовый Урок 05 — Реализация создание объектов
В уроке рассказывается как создавать объекты в сцене в реальном времени (runtime), используя префабы и команду Instantiate (инстанциирование)
Если вы хотите добавлять объекты на сцену, когда сцена уже загружена, то вам требуется использовать скрипты, а точнее команду Instantiate().
Загрузите сцену из Базового урока 03 (Префабы) или создайте такую же новую. В нашей сцене присутствует префаб BouncyBox.
Нажмите Play и убедитесь, что куб по-прежнему падает и отталкивается от поверхностей.
Теперь удалите со сцены экземпляр BouncyBox.
После этого добавьте пустой объект (напоминаю, GameObject->Create Empty или Ctrl + Shift + N в Windows, Cmd + Shift + N в MacOS). Расположите его примерно в том месте, где раньше был экземпляр BouncyBox.
Создадим C#-Скрипт и назовем его Creater. Начнем редактирование скрипта. Заведем открытую (public) переменную типа GameObject и назовем ее thePrefab. Модификатор public требуется указывать, если, например, вы хотите передавать значение переменной через Inspector View. После чего в теле функции Start() создадим еще один GameObject (с именем instance) и проинициализируем его значением с помощью статической функции Instantiate().
Рассмотрим метод Instantiate() подробнее.
Метод клонирует объект original с заданными вектором положения (position) и кватернионом поворота (rotation).
Тип Vector3 является обычным 3х компонентым вектором (аналогично вектору из R 3 ).
Тип Quaternion — кватернион, задающий поворот объекта.
Добавьте скрипт к пустому объекту (c именем GameObject).Напоминаю, поскольку thePrefab объявлен с модификатором public, вы можете задавать его начальное значение прямо в Inspector View (у соответствующего компонента, то есть в нашем случае это Creator у GameObject’а). Перетащите наш префаб в место указания значения (или выберете его из списка, кликнув на кружок справа).
Нажмем Play и увидим, что на сцене появился наш прыгающий кубик.
Но наш кубик прыгает просто вверх и вниз, потому что не имеет начального угла поворота. Выберите GameObject и поверните его под небольшим углом.
Теперь, нажав Play, вы увидите, что кубик падает и отталкивается под различными углами.
Дополнительные материалы:
Базовый Урок 06 — Простой таймер
В данном уроке рассказывается как в Unit при помощи скриптов
создавать простой таймер, используя Time.deltaTime и переменную типа float.
Воспользуемся сценой из предыдущего урока (с пустым игровым объектом,
генерирующим экземпляры префаба, т.е. BouncyBox).
Создадим С#-скрипт и назовем его Timer. Добавим переменную myTimer, и напишем следующий код.
Сохраняем скрипт и переключаемся назад в Unity. Добавим скрипт к объекту GameObject.
Напомню, т.к. myTimer объявлена открытой (public), то в Inspector View вы можете менять ее начальное значение.
Жмем Play. Как только значение myTimer упадет до нуля, в статус баре вы увидите строку GAME OVER. Значение переменной myTimer будет продолжать опускаться (это можно увидеть в Inspector View).
Для того, чтобы переменная myTimer не опускалась ниже нуля, добавим еще одно ветвление в функцию Update(), в итоге мы получаем следующий код:
Нажмем Play и проследим за поведением переменной myTimer. Когда ее значение будет достаточно близким к нулю, то оно перестанет изменяться.
Дополнительные материалы:
Базовый Урок 07 — Основы движения
В уроке рассказывается, как двигать объекты c помощью функции transform.Translate.
Создадим сцену с кубом, камерой и источником света.
Создадим новый C#-скрипт и назовем его Move.
Поскольку движение должно быть непрерывно во времени, то основной код будет располагаться в методе Update(). Вызовем функцию Translate, объекта transform и передадим ей в качестве параметра Vector3(0, 0, 1). Получим следующий код:
Разберемся подробнее в коде. Тут transform — это объект класса Transform, привязанный к нашему объекту. Метод Translate() двигает объект вдоль вектора на расстояние равное его длине (параллельный перенос).
Сохраним наш скрипт и добавим его к нашему кубу. Нажмите Play и увидите как куб стремительно улетает вдоль оси Oz.
Давайте уменьшим скорость движения, например, умножив наш вектор на Time.deltaTime, то есть:
Нажмите Play и убедитесь, что куб начинает двигаться заметно медленнее.
Можно сделать наш скрипт более удобным в использовании, если скорость задать не фиксированным вектором, а через переменную. Заведем public переменную типа float и назовем ее speed. С помощью этой переменной можно будет задавать начальную скорость через Inspector View (по умолчанию она будет равна 5.0f):
Сохраним скрипт и убедимся, что в Inspector View у компонента Move появилась переменная Speed.
Посмотрите, как будет меняться скорость движения нашего объекта в соответствии с заданным начальным значением этой переменной. Например, при Speed = 3 скорость объекта не очень быстрая, но и не медленная.
Примечение: Для выражения Vector3(0.0f, 0.0f, 1.0f) существует короткая (но видимо чуть более медленная, если не прав, прошу поправить) запись Vector3.forward.
Кусок кода из обертки:
Дополнительные материалы:
Базовый Урок 08 — Основы движения с помощью силы.
В уроке рассказывается как c помощью приложения силы двигать физическое тело (Rigidbody).
Если у вас на сцене есть объект с компонентом Rigidbody, то нужно задавать ему движение с помощью приложения силы (передав таким образом все расчеты движения физическому движку игры). В противном случае вы можете начать конфликтовать с физикой объекта. Мы по-прежнему используем сцену из Базового урока 03.
Создадим C#-скрипт и назовем его Force. В методе Start() вызовем метод AddForce() компонента rigidbody (cвязанного с нашим объектом) и передадим ему вектор приложенной силы Vector3(0.0f, 0.0f, power). В классе заведем переменную типа float с именем power и значением, по умолчанию равным 500.0f:
Сохраним скрипт и добавим его к нашему объекту (или префабу). Теперь, если нажать Play, вы увидите как куб падает не вниз а под углом, из-за воздействия силы приложенной вдоль оси Oz.