как создать объект в unity через скрипт
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.
Создание объектов
Некоторые игры имеют постоянное количество объектов на сцене, однако обычно персонажи, пули, сокровища и другие объекты создаются и удаляются во время игры. В 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() и удаление (уничтожения) себя.
Все скрипты написаны. Поздравляем! Осталось правильно разместить все объекты на сцене и не забыть указать им друг на друга.
Создание и Использование Скриптов
Unity изначально поддерживает три языка программирования:
Изучение искусства программирования и использования этих языкам выходит за рамки данного введения. Однако есть множество книг, обучающих материалов и ресурсов для изучения программирования в среде Unity. Посетите Обучающий раздел на нашем сайте для получения подробной информации.
Создание скриптов
В отличии от других ассетов, скрипты обычно создаются непосредственно в Unity. Вы можете создать скрипт используя меню Create в левом верхнем углу панели Project или выбрав Assets > Create > C# Script (или JavaScript/Boo скрипт) в главном меню.
Новый скрипт будет создан в папке, которую вы выбрали в панели Project. Имя нового скрипта будет выделено, предлагая вам ввести новое имя.
Лучше ввести новое имя скрипта сразу после создания чем изменять его потом. Имя, которое вы введете будет использовано, чтобы создать начальный текст в скрипте, как описано ниже.
Структура файла скрипта
После двойного щелчка на скрипте в Unity, он будет открыт в текстовом редакторе. По умолчанию Unity будет использовать MonoDevelop, но вы можете выбрать любой редактор из панели External Tools в настройках Unity.
Содержимое файла будет выглядеть примерно так:
Заметка для опытных программистов: вы можете быть удивлены, что инициализация объекта выполняется не в функции-конструкторе. Это потому, что создание объектов обрабатывается редактором и происходит не в начале игрового процесса, как вы могли бы ожидать. Если вы попытаетесь определить конструктор для скриптового компонента, он будет мешать нормальной работе Unity и может вызвать серьезные проблемы с проектом.
A UnityScript script works a bit differently to C# script:
Здесь функции Start и Update имеют такое же значение, но класс не объявлен явно. Предполагается, что скрипт сам по себе определяет класс; он будет неявно производным от MonoBehaviour и получит своё имя от имени файла скриптового ассета.
Управление игровым объектом
Как было сказано ранее, скрипт определяет только план компонента и, таким образом, никакой его код не будет активирован до тех пор, пока экземпляр скрипта не будет присоединен к игровому объекту. Вы можете прикрепить скрипт перетаскиванием ассета скрипта на игровой объект в панели Hierarchy или через окно Inspector выбранного игрового объекта. Имеется также подменю Scripts в меню Component, которое содержит все скрипты, доступные в проекте, включая те, которые вы создали сами. Экземпляр скрипта выглядит так же, как и другие компоненты в окне Inspector:-
После присоединения скрипт начнет работать, когда вы нажмете Play и запустите игру. Вы можете проверить это добавив следующий код в функцию Start:-
Создание и Использование Скриптов
Поведение игровых объектов контролируется с помощью компонентов (Components), которые присоединяются к ним. Несмотря на то, что встроенные компоненты Unity могут быть очень разносторонними, вскоре вы обнаружите, что вам нужно выйти за пределы их возможностей, чтобы реализовать ваши собственные особенности геймплея. Unity позволяет вам создавать свои компоненты, используя скрипты. Они позволяют активировать игровые события, изменять параметры компонентов, и отвечать на ввод пользователя каким вам угодно способом.
Unity supports the C# programming language natively. C# (pronounced C-sharp) is an industry-standard language similar to Java or C++.
Изучение искусства программирования и использования этих языкам выходит за рамки данного введения. Однако есть множество книг, обучающих материалов и ресурсов для изучения программирования в среде Unity. Посетите Обучающий раздел на нашем сайте для получения подробной информации.
Создание скриптов
Unlike most other assets, scripts are usually created within Unity directly. You can create a new script from the Create menu at the top left of the Project panel or by selecting Assets > Create > C# Script from the main menu.
Новый скрипт будет создан в папке, которую вы выбрали в панели Project. Имя нового скрипта будет выделено, предлагая вам ввести новое имя.
Лучше ввести новое имя скрипта сразу после создания чем изменять его потом. Имя, которое вы введете будет использовано, чтобы создать начальный текст в скрипте, как описано ниже.
Структура файла скрипта
When you double-click a script Asset in Unity, it will be opened in a text editor. By default, Unity will use Visual Studio, but you can select any editor you like from the External Tools panel in Unity’s preferences (go to Unity > Preferences).
Содержимое файла будет выглядеть примерно так:
Скрипт взаимодействует с внутренними механизмами Unity за счет создания класса, наследованного от встроенного класса, называемого MonoBehaviour. Вы можете думать о классе как о своего рода плане для создания нового типа компонента, который может быть прикреплен к игровому объекту. Каждый раз, когда вы присоединяете скриптовый компонент к игровому объекту, создается новый экземпляр объекта, определенный планом. Имя класса берется из имени, которое вы указали при создании файла. Имя класса и имя файла должны быть одинаковыми, для того, чтобы скриптовый компонент мог быть присоединен к игровому объекту.
Заметка для опытных программистов: вы можете быть удивлены, что инициализация объекта выполняется не в функции-конструкторе. Это потому, что создание объектов обрабатывается редактором и происходит не в начале игрового процесса, как вы могли бы ожидать. Если вы попытаетесь определить конструктор для скриптового компонента, он будет мешать нормальной работе Unity и может вызвать серьезные проблемы с проектом.
Управление игровым объектом
Как было сказано ранее, скрипт определяет только план компонента и, таким образом, никакой его код не будет активирован до тех пор, пока экземпляр скрипта не будет присоединен к игровому объекту. Вы можете прикрепить скрипт перетаскиванием ассета скрипта на игровой объект в панели Hierarchy или через окно Inspector выбранного игрового объекта. Имеется также подменю Scripts в меню Component, которое содержит все скрипты, доступные в проекте, включая те, которые вы создали сами. Экземпляр скрипта выглядит так же, как и другие компоненты в окне Inspector:-
После присоединения скрипт начнет работать, когда вы нажмете Play и запустите игру. Вы можете проверить это добавив следующий код в функцию Start:-
Debug.Log is a simple command that just prints a message to Unity’s console output. If you press Play now, you should see the message at the bottom of the main Unity editor window and in the Console window (menu: Window > General > Console).
2018–03–19 Page amended
MonoDevelop replaced by Visual Studio from 2018.1
ScriptableObject: Как работают скриптовые объекты?
В этой статье попробуем разобрать что такое Scriptable object, зачем они нужны и как их использовать.
Работать с файлами в редакторе unity достаточно просто. Каждый файл отображает только свои параметры, если это изображение, то мы видим настройки разрешения, детализации и тд, если это текст, то мы можем увидеть, что написано в нем, а если это 3D модель, то можем увидеть ее в окошке Preview и даже покрутить. Все это конечно удобно, но что если нам понадобится особый объект который мог бы сочетать в себе несколько типов данных одновременно, к примеру сделать так, чтобы в одном файле хранилась и картинка и, допустим, текст с ее описанием? Для решения этой проблемы и был введен особый тип объектов в unity – Scriptable object.
Scriptable object (скриптовый объект) это по сути, объект определенного типа, который может хранить пользовательские данные любого типа в виде файла. Для тех кто знаком немного с сериализацией, может возникнуть небольшое противоречие, ведь зачем мне скриптовый объект, если я и так смогу посредством сериализации сохранить и картинку и текст, и что угодно в любой файл!? Дело в том что скриптовый объект работает по такому же принципу как и любой другой объект в unity, за счет чего между ними сохраняется взаимосвязь, где вам не нужно создавать дополнительные, специальные инструменты для того, чтобы разные объекты могли взаимодействовать со скриптовый объектом.
Попробуем на примере разобрать, как выглядят скриптовые объекты и чем они отличаются от любых других объектов unity. Создадим простой скрипт ImageData, который будет обычным классом и хранить в себе изображение Sprite, и текст с его описанием.
Если создать экземпляр данного класса с помощью оператора new :
ImageData data = new ImageData ();
то этот экземпляр будет существовать только в оперативной памяти компьютера до тех пор, пока программа не завершит свою работу, после чего память очистится и объект ImageData будет уничтожен. Чтобы можно было постоянно хранить этот объект в проекте после создания, необходимо унаследовать ImageData от класса ScriptableObject и создать уже не просто “виртуальный” экземпляр объекта, а его постоянную форму в виде файла.
Создавать экземпляры скриптовых объектов можно вызвав статический метод CreateInstance класса ScriptableObject. Выполнять это действие необходимо только в редакторе, для чего воспользуемся методами “быстрого” доступа – это статические методы, которые вызываются с помощью контекстного меню внутри редактора.
В самом методе создадим экземпляр скриптового объекта ImageData.
При вызове статического метода CreateInstance, в скобки передается тип создаваемого объекта, в нашем случае это тип ImageData. После того как экземпляр создан, необходимо его сохранить в проекте, для чего воспользуемся специальным классом по работе с ассетами в редакторе – AssetDatabase и его статичеким методом CreateAsset для сохранения объектов в виде файла.
Теперь в папке Assets у нас появился новый файл скриптового объекта в который мы можем поместить изображение и текст с описанием.
Итак, экземпляр скриптового объекта ImageData перешел из “виртуального” вида и хранится теперь в постоянной памяти вместо оперативной. Этот файл мы можем редактировать, удалять, перемещать и тд, в каком то смысле теперь объект стал “осязаем”, что намного облегчает работу с ним. Самое главное преимущество скриптовых объектов перед другими видами файлов в том, что эти объекты могут хранить самые необходимые данные, точнее – только те, которые вы укажете.
Для сравнения возьмем обычный префаб. Префаб – это сложный GameObject который может содержать в себе другие GameObject’ы, а также кучу компонентов, которые вам могут показаться совершенно бесполезными.
В скриптовом объекте вы указываете только те данные, которые вас интересуют, без лишних компонентов и других данных, при этом сохраняются все возможности работы со скриптовым объектом как и с любым другим unity объектом.
Во вторых – скриптовые объекты очень хорошо оптимизируют процесс работы игры, тем что отлично экономят память, когда большое кол-во объектов ссылаются на одни и те же данные.
К примеру: на сцене есть 1000 GameObject’ов, у каждого объекта есть компонент, в котором необходимо указать ссылку на изображение, ее размеры Vector2 и текст с ее описанием, в этом случае все 1000 объектов будут создавать свои уникальные ссылки на эти данные, что в общем кол-ве будет давать 3000 (1000 объектов умножить на 3 вида данных) уникальных ссылок, что совершенно не нужно, так как достаточно просто создать один скриптовый объект со всеми этими данными и передавать в компонент одну ссылку на скриптовый объект вместо 3х.
И в третьих – заменяемость. Для создания копий экземпляра скриптового объекта, достаточно использовать Instantiate, как и при создании копии любого префаба, после чего получаем абсолютно новую и независимую копию объекта.
Использовать скриптовый объекты так же легко как и любые другие объекты в unity.
В примере используется массив скриптовых объектов, чтобы переключать изображения по щелчку мыши. Панель UI с изображениями на сцене одна как и текст с описанием, а компонент, в свою очередь, просто имеет ссылки на скриптовые объекты с другими изображениями и описаниями к ним.
В самом компоненте, для получения ссылок на скриптовые объекты необходимо просто указать тип ImageData.
Скриптовые объекты и ООП
В начале статьи мы разбирали простой класс ImageData, который еще не был унаследован от ScriptableObject, и создавали экземпляры данного класса с помощью оператора new. Экземпляры скриптовых объектов также можно создавать с помощью этого оператора.
К примеру, усовершенствуем немного класс ImageData и добавим ему конструктор, в котором будет указывать изображение и текст с описанием.
Теперь можно создать экземпляр класса ImageData использую его конструктор.
Данная конструкция создает “виртуальный” экземпляр скриптового объекта, это именно то, с чем мы боролись использую скриптовые объект – перейти от “виртуального” типа к “физическому”. Хотя такая конструкция создания очень удобная при создании сложных экземпляров, сохранять такие экземпляры нельзя. Для решения данной проблемы необходимо поместить “виртуальный” экземпляр в “физический” шаблон, созданный через статический метод CreateInstance.
В методе CreateImageData создается новый экземпляр скриптового объекта ImageData, только в этот раз с помощью оператора new. После чего экземпляр передаем в метод SaveInstance для сохранения его в виде постоянного файла. Так как сохранять “виртуальные” экземпляры не получится, необходимо создать его “физический” шаблон скриптового объекта такого же типа как и оригинал, после чего просто передать на него ссылку и сохранить.
В переменную saveObject помещаем новый “физический” шаблон такого же типа как и оригинал, для этого в новом статическом метод CreateInstance указываем тип передаваемого объекта, вызвав его метод GetType.
После создания шаблона, достаточно передать ему ссылку на оригинал после чего можно сохранять объект в виде файла в проекте при помощи AssetDataBase.
Скриптовые объекты могут вам очень пригодится когда необходимо создать постоянную базу данных в виде файла, которую удобно редактировать, перемещать и передавать другим объектам. Эти объекты одновременно совмещают два способа работы: программный – на уровне кода, и файловый.