как обратиться к скрипту на объекте unity

Управление игровыми объектами (GameObjects) с помощью компонентов

В редакторе Unity вы изменяете свойства Компонента используя окно Inspector. Так, например, изменения позиции компонента Transform приведет к изменению позиции игрового объекта. Аналогично, вы можете изменить цвет материала компонента Renderer или массу твёрдого тела (RigidBody) с соответствующим влиянием на отображение или поведение игрового объекта. По большей части скрипты также изменяют свойства компонентов для управления игровыми объектами. Разница, однако, в том, что скрипт может изменять значение свойства постепенно со временем или по получению ввода от пользователя. За счет изменения, создания и уничтожения объектов в заданное время может быть реализован любой игровой процесс.

Обращение к компонентам

Наиболее простым и распространенным является случай, когда скрипту необходимо обратиться к другим компонентам, присоединенных к тому же GameObject. Как упоминалось во разделе Введение, компонент на самом деле является экземпляром класса, так что первым шагом будет получение ссылки на экземпляр компонента, с которым вы хотите работать. Это делается с помощью функции GetComponent. Типично, объект компонента сохраняют в переменную, это делается в C# посредством следующего синтаксиса:

В UnityScript синтаксис немного отличается:

Как только у вас есть ссылка на экземпляр компонента, вы можете устанавливать значения его свойств, тех же, которые вы можете изменить в окне Inspector:

Имейте ввиду, что нет причины, по которой вы не можете иметь больше одного пользовательского скрипта, присоединенного к одному и тому же объекту. Если вам нужно обратиться к одному скрипту из другого, вы можете использовать, как обычно, GetComponent, используя при этом имя класса скрипта (или имя файла), чтобы указать какой тип Компонента вам нужен.

Если вы попытаетесь извлечь Компонент, который не был добавлен к Игровому Объекту, тогда GetComponent вернет null; возникнет ошибка пустой ссылки при выполнении (null reference error at runtime), если вы попытаетесь изменить какие-либо значения у пустого объекта.

Обращение к другим объектам

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

Связывание объектов через переменные

Переменная будет видна в окне Inspector, как и любые другие:

как обратиться к скрипту на объекте unity

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

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

Соединение объектов через переменные наиболее полезно, когда вы имеете дело с отдельными объектами, имеющими постоянную связь. Вы можете использовать массив для хранения связи с несколькими объектами одного типа, но связи все равно должны быть заданы в редакторе Unity, а не во время выполнения. Часто удобно находить объекты во время выполнения, и Unity предоставляет два основных способа сделать это, описанных ниже.

Нахождение дочерних объектов

Иногда игровая сцена может использовать несколько объектов одного типа, таких как враги, путевые точки и препятствия. Может возникнуть необходимость отслеживания их в определенном скрипте, который управляет или реагирует на них (например, все путевые точки могут потребоваться для скрипта поиска пути). Можно использовать переменные для связывания этих объектов, но это сделает процесс проектирования утомительным, если каждую новую путевую точку нужно будет перетащить в переменную в скрипте. Аналогично, при удалении путевой точки придется удалять ссылку на отсутствующий объект. В случаях, наподобие этого, чаще всего удобно управлять набором объектов, сделав их дочерними одного родительского объекта. Дочерние объекты могут быть получены, используя компонент Transform родителя (так как все игровые объекты неявно содержат Transform):

Вы можете также найти заданный дочерний объект по имени, используя функцию Transform.Find:

Источник

Методы организации взаимодействия между скриптами в Unity3D

Вступление

Подход 1. Назначение через редактор Unity3D

Пусть у нас в проекте есть два скрипта. Первый скрип отвечает за начисление очков в игре, а второй за пользовательский интерфейс, который, отображает количество набранных очков на экране игры.
Назовем оба скрипта менеджерами: ScoresManager и HUDManager.
Каким же образом менеджеру, отвечающему за меню экрана можно получить текущее количество очков от менеджера, отвечающего за начисление очков?
Предполагается, что в иерархии объектов(Hierarchy) сцены существуют два объекта, на один из которых назначен скрипт ScoresManager, а на другой скрипт HUDManager.
Один из подходов, содержит следующий принцип:
В скрипте UIManager определяем переменную типа ScoresManager:

Но переменную ScoresManager необходимо еще инициализировать экземпляром класса. Для этого выберем в иерархии объектов объект, на который назначен скрипт HUDManager и в настройках объекта увидим переменную ScoresManager со значением None.

как обратиться к скрипту на объекте unity

Далее, из окна иерархии перетаскиваем объект, содержащий скрипт ScoresManager в область, где написано None и назначаем его объявленной переменной:

как обратиться к скрипту на объекте unity

После чего, у нас появляется возможность из кода HUDManager обращаться к скрипту ScoresManager, таким образом:

Все просто, но игра, не ограничивается одними набранными очками, HUD может отображать текущие жизни игрока, меню доступных действия игрока, информацию о уровне и многое другое. Игра может насчитывать в себе десятки и сотни различных скриптов, которым нужно получать информацию друг от друга.
Чтобы получить в одном скрипте данные из другого скрипта нам каждый раз придется описывать переменную в одном скрипте и назначать (перетаскивать вручную) ее с помощью редактора, что само по себе нудная работа, которую легко можно забыть сделать и потом долго искать какая из переменных не инициализирована.
Если мы захотим что-то отрефакторить, переименовать скрипт, то все старые инициализации в иерархии объектов, связанные с переименованным скриптом, сбросятся и придется их назначать снова.
В то же время, такой механизм не работает для префабов (prefab) — динамического создания объектов из шаблона. Если какому-либо префабу нужно обращаться к менеджеру, расположенному в иерархии объектов, то вы не сможете назначить самому префабу элемент из иерархии, а придется сначала создать объект из префаба и после этого программно присвоить экземпляр менеджера переменной только что созданного объекта. Не нужная работа, не нужный код, дополнительная связанность.
Следующий подход решает все эти проблемы.

Подход 2. «Синглтоны»

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

Примеры

Как правило, в единственном экземпляре существуют скрипты, отвечающие за общую логику пользовательского интерфейса, за проигрывание музыки, за отслеживание условий завершения уровня, за управление системой заданий, за отображение спецэффектов и так далее.
В то же время, скрипты игровых объектов существуют в большом количестве экземпляров: каждая птичка из «Angry Birds» управляется экземпляром скрипта птички со своим уникальным состоянием; для любого юнита в стратегии создается экземпляр скрипта юнита, содержащий его текущее количество жизней, позицию на поле и личную цель; поведение пяти разных иконок обеспечивается различными экземплярами одних и тех же скриптов, отвечающих за это поведение.
В примере из предыдущего шага скрипты HUDManager и ScoresManager всегда существуют в единственном экземпляре. Для их взаимодействия друг с другом применим паттерн «синглтон» (Singleton, он же одиночка).
В классе ScoresManager опишем статическое свойство типа ScoresManager, в котором будет храниться единственный экземпляр менеджера очков:

Осталось инициализировать свойство Instance экземпляром класса, который создает среда Unity3D. Так как ScoresManager наследник MonoBehaviour, то он участвует в жизненном цикле всех активных скриптов в сцене и во время инициализации скрипта у него вызывается метод Awake. В этот метод мы и поместить код инициализации свойства Instance:

После чего, использовать ScoresManager из других скриптов можно следующим образом:

Теперь нет необходимости в HUDManager описывать поле типа ScoresManager и назначать его в редакторе Unity3D, любой «скрипт-менеджер» может предоставлять доступ к себе через статическое свойство Instance, которое будет инициализировать в функции Awake.

Плюсы

— нет необходимости описывать поле скрипта и назначать его через редактор Unity3D.
— можно смело рефакторить код, если что и отвалится, то компилятор даст знать.
— к другим «скриптам-менеджерам» теперь можно обращаться из префабов, через свойство Instance.

Минусы

— подход обеспечивает доступ только к «скриптам-менеджерам», существующим в единственном экземпляре.
— сильная связанность.
На последнем «минусе» остановимся подробнее.
Пусть мы разрабатываем игру, в которой есть персонажи (unit) и эти персонажи могут погибать (die).
Где-то находится участок кода, который проверяет не погиб ли наш персонаж:

Получается, что персонаж после совей смерти должен разослать всем компонентам, которые в ней заинтересованы этот печальный факт, он должен знать о существовании этих компонентов и должен знать, что они им интересуются. Не слишком ли много знаний, для маленького юнита?
Так как игра, по логике, очень связанная структура, то и события происходящие в других компонентах интересуют третьи, юнит тут ничем не особенный.
Примеры таких событий (далеко не все):
— Условие прохождение уровня зависит от количества набранных очков, набрали 1000 очков – прошли уровень (LevelConditionManager связан с ScoresManager).
— Когда набираем 500 очков, достигаем важную стадию прохождения уровня, нужно проиграть веселую мелодию и визуальный эффект (ScoresManager связан с EffectsManager и SoundsManager).
— Когда персонаж восстанавливает здоровье, нужно проиграть эффект лечения над картинкой персонажа в панели персонажа (UnitsPanel связан с EffectsManager).
— и так далее.
В результате таких связей мы приходим к картине похожей на следующую, где все про всех все знают:

как обратиться к скрипту на объекте unity

Пример со смертью персонажа немного преувеличен, сообщать о смерти (или другом событии) шести разным компонентам не так часто приходится. Но варианты, когда при каком-то событии в игре, функция, в которой произошло событие, сообщает об этом 2-3 другим компонентам встречается сплошь и рядом по всему коду.
Следующий подход пытается решает эту проблему.

Подход 3. Мировой эфир (Event Aggregator)

Введем специальный компонент «EventAggregator», основная функция которого хранить список событий, происходящих в игре.
Событие в игре — это функционал, предоставляющий любому другому компоненту возможность как подписаться на себя, так и опубликовать факт совершения этого события. Реализация функционала события может быть любой на вкус разработчика, можно использовать стандартные решения языка или написать свою реализацию.
Пример простой реализации события из прошлого примера (о смерти юнита):

Добавляем это событие в «EventAggregator»:

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

А любой компонент, которому интересно это событие, может отреагировать на него следующим образом (на примере менеджера отвечающего за количество набранных очков):

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

как обратиться к скрипту на объекте unity

Замечание

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

Плюсы

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

Минусы

— нужно постоянно описывать новые события и добавлять их в мир.
— нарушение функциональной атомарности.

Последний минус рассмотрим более детально

Представим, что у нас есть объект «ObjectA», в котором вызывается метод «MethodA». Метод «MethodA», состоит из трех шагов и вызывает внутри себя три других метода, которые выполняют эти шаги последовательно («MethodA1», «MethodA2» и «MethodA3»). Во втором методе «MethodA2» происходит публикация какого-то события. И тут происходит следующее: все кто подписан на это событие начнут его обрабатывать, выполняя какую-то свою логику. В этой логике тоже может произойти публикация других событий, обработка которых также может привести к публикации новых событий и так далее. Дерево публикаций и реакции в отдельных случаях может очень сильно разрастись. Такие длинные цепочки крайне тяжело отлаживать.
Но самая страшная проблема, которая тут может произойти, это когда одна из веток цепочки приводит обратно в «ObjectA» и начинает обрабатывать событие путем вызова какого-то другого метода «MethodB». Получается, что метод «MethodA» у нас еще не выполнил все шаги, так как был прерван на втором шаге, и содержит сейчас в себе не валидное состояние (в шаге 1 и 2 мы изменили состояние объекта, но последнее изменение из шага 3 еще не сделали) и при этом начинается выполняться «MethodB» в этом же объекте, имея это не валидное состояние. Такие ситуации порождают ошибки, очень сложно отлавливаются, приводят к тому, что надо контролировать порядок вызова методов и публикации событий, когда по логике этого делать нет необходимости и вводят дополнительную сложность, которую хотелось бы избежать.

Решение

Решить описанную проблему не сложно, достаточно добавить функционал отложенной реакции на событие. В качестве простой реализации такого функционала мы можем завести хранилище, в которое будем складывать произошедшие события. Когда событие произошло, мы не выполняем его немедленно, а просто сохраняем где-то у себя. И в момент наступления очереди выполнения функционала какой-то компоненты в игре (в методе Update, например) мы проверяем на наличие произошедших событий и выполняем обработку, если есть такие события.
Таким образом, при выполнении метода «MethodA» не происходит его прерывание, а опубликованное событие все заинтересованные записывают себе в специальное хранилище. И только после того как к заинтересованным подписчикам дойдет очередь, они достанут из хранилища событие и обработают его. В этот момент весь «MethodA» будет завершен и «ObjectA» будет иметь валидное состояние.

Источник

Как обратиться к скрипту на объекте unity

200?’200px’:»+(this.scrollHeight+5)+’px’);»>
using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour
<

void OnTriggerEnter(Collider SonicEnemy) <
targScript = gameObject.Find(«ИмяОбьекта»).GetComponent(«SonicCollision»);
if(SonicEnemy.gameObject.name == «Enemy») <
targScript.ring = 0;
Debug.Log(«targScript.ring»);
>
>
>

как обратиться к скрипту на объекте unityкак обратиться к скрипту на объекте unity
Fr0sTДата: Воскресенье, 06 Мая 2012, 15:34 | Сообщение # 9
как обратиться к скрипту на объекте unity

как обратиться к скрипту на объекте unity

Аннет,оба скрипта висят на сонике.Не выходит.
как обратиться к скрипту на объекте unity
как обратиться к скрипту на объекте unity
как обратиться к скрипту на объекте unity

как обратиться к скрипту на объекте unityкак обратиться к скрипту на объекте unity
ЛевшаДата: Воскресенье, 06 Мая 2012, 16:45 | Сообщение # 10
как обратиться к скрипту на объекте unity

как обратиться к скрипту на объекте unity

как обратиться к скрипту на объекте unity

Я просто чтото не дадумался сначала,а щас вод допер,ну всёравно огромное спасибо!

Добавлено (06.05.2012, 19:05)
———————————————
А я вот так написал и у меня он теперь сквозь кольца проходит,что там не так.Я только начинаю скрипты писать если что,так что у меня много ошибок)

200?’200px’:»+(this.scrollHeight+5)+’px’);»> using UnityEngine;
using System.Collections;

public class RingCollector: MonoBehaviour
<
public int ring = 0;

void OnTriggerEnter(Collider RingCollider,Collider EnemyCollider)
<
if(RingCollider.gameObject.name == «Ring»)
<
Destroy(RingCollider.gameObject);
ring ++;
Debug.Log(ring);
>
else if(EnemyCollider.gameObject.name == «Enemy»)
<
ring = 0;
Debug.Log(ring);
>
>

Script error: OnTriggerEnter
The message must have 0 or 1 parameters.
The message will be ignored.
как обратиться к скрипту на объекте unity
как обратиться к скрипту на объекте unity
как обратиться к скрипту на объекте unity

Источник

Создание и Использование Скриптов

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:-

как обратиться к скрипту на объекте unity

После присоединения скрипт начнет работать, когда вы нажмете Play и запустите игру. Вы можете проверить это добавив следующий код в функцию Start:-

Источник

Unity: знакомство со Scriptable Objects

как обратиться к скрипту на объекте unity

В этом туториале вы узнаете, как создавать и использовать Scriptable Objects в Unity. Scriptable Objects помогут усовершенствовать ваш рабочий процесс, снизить объём занимаемой памяти и даже позволят разделить архитектуру кода.

Согласно документации Unity, ScriptableObject — это код класса, позволяющий создавать в игре Scriptable Objects для хранения больших объёмов общих данных, не зависящих от экземпляров скриптов.

Существует множество причин для использования Scriptable Objects в Unity. Они могут снизить объём используемой под каждый дополнительный префаб памяти, потому что по своей сути Scriptable Object следуют паттерну разработки Flyweight.

Ещё одно преимущество Scriptable Objects, которое будет основной темой этого туториала, заключается в их использовании для удобной пересылки данных. Мы рассмотрим это свойство на примере создания лавки торговца мечами, в которой будут отображаться параметры, цены и описания различных мечей.

Примечание: в этом туториале подразумевается, что вы знакомы с редактором Unity. Вы должны разбираться в том, как править код в редакторе кода и иметь базовые знания C#. Если вам нужно повысить свои навыки Unity, изучите другие туториалы по Unity.

Приступаем к работе

Начнём с загрузки материалов, которые нам потребуются.

Распакуйте скачанный файл в удобное для вас место и откройте в Unity проект Scriptable Object Tutorial-Starter.

Вы должны увидеть следующую папку, созданную как часть заготовки проекта:

как обратиться к скрипту на объекте unity

Создание Scriptable Object

Для начала перейдите в сцену Sword Merchant. Она должна выглядеть следующим образом:

как обратиться к скрипту на объекте unity

Подготовка Scriptable Object

Настало время для создания первого Scriptable Object!

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

Внутри этого класса начнём с наследования из ScriptableObject вместо MonoBehaviour :

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

Заполним скрипт сериализированными полями, в которых будут содержаться все данные, соответствующие информации, отображаемой в UI Sword Merchant.

В Unity атрибут SerializeField позволяет иметь частные переменные скрипта, доступные в Инспекторе. Он позволит задавать значения в редакторе, не предоставляя доступ к переменной из других скриптов.

Каждому мечу потребуется собственная уникальная реализация Scriptable Object SwordData. Но прежде чем мы сможем создать эти реализации, нам нужно добавить Scriptable Object в Asset Menu.

Добавим наш Scriptable Object в Asset Menu, добавив к классу SwordData следующий атрибут:

как обратиться к скрипту на объекте unity

Также можно нажать правой клавишей мыши в окне Project и тоже увидеть новый ассет Sword Data:

как обратиться к скрипту на объекте unity

Добавление данных

Упорядочим проект, создав в папке Scripts папку с названием Scriptable Objects, а внутри этой папки — ещё одну папку с названием Sword Data.

Внутри только что созданной папки Sword Data folder создадим наш первый ассет Sword Data.

У нового ассета Sword Data по-прежнему должно быть указанное ранее имя по умолчанию fileName. Выберите ассет и дублируйте его шесть раз (Ctrl/Cmd + D), чтобы создать семь ассетов Sword Data, по одному для каждого из мечей. Теперь переименуйте каждый ассет в соответствии с префабами:

как обратиться к скрипту на объекте unity

Нажмите на первый ассет Sword Data в папке Sword Data и посмотрите на окно Inspector:

как обратиться к скрипту на объекте unity

Здесь мы видим ассет, в котором будет храниться информация о конкретном мече. Заполните информацию для каждого меча. Постарайтесь дать им уникальное описание, стоимость в золоте и урон при атаке. В поле Icon Sprite используйте соответствующие спрайты, расположенные в папке Sword Icons:

как обратиться к скрипту на объекте unity

Поздравляю! Вы создали Scriptable Object и настроили с помощью этого Scriptable Object несколько ассетов.

Использование Scriptable Object

Теперь мы приступим к получению данных из этих Scriptable Objects.

Во-первых, нам нужно добавить несколько публичных методов-получателей (getter methods), чтобы другие скрипты могли получать доступ к частным полям внутри Scriptable Object. Откроем SwordData.cs и допишем под добавленными ранее полями следующее:

Откроем Sword.cs и добавим следующий код:

Вот, что мы добавили этим кодом:

как обратиться к скрипту на объекте unity

Нажмите на Play (Ctrl/Cmd + P) в редакторе Unity, а затем щёлкните самый левый меч:

как обратиться к скрипту на объекте unity

В консоль должна выводиться информация, напоминающие данные, переданные из ассета Sword Data.

Scriptable Objects позволяют с лёгкостью заменять эти данные. Попробуйте вставлять разные Sword Data Scriptable Object в поле Sword Data меча.

Scriptable Objects на основе событий

Итак, мы создали Scriptable Object, и вы увидели, как можно получать доступ к его данным внутри игры. Но нам всё равно нужно интегрировать Sword Data с UI!

Для этого можно использовать быстрый и грязный паттерн Singleton. Однако мы теперь обладаем другими возможностями…

…а именно Scriptable Objects! Воспользуемся ими для создания чистого и аккуратно разделённого на части кода.

В этом разделе вы узнаете, как создавать Game Events с помощью класса UnityEvent.

Game Events и Listeners

В папке Scripts создайте два скрипта: GameEvent.cs и GameEventListener.cs. Они зависят друг от друга, поэтому чтобы избавиться от ошибок, нужно создать оба.

Вот что делает приведённый выше код:

В показанном выше коде происходит дальнейшее развитие проекта:

Подготовка редактора

Вернитесь в редактор Unity и создайте новую папку Game Events в Scripts >> ScriptableObjects. Затем создайте семь Game Events из Asset Menu, как мы это делали для каждого ассета Sword Data. Разместите их в новой папке Game Events.

как обратиться к скрипту на объекте unity

Замените код внутри скрипта Sword.cs следующими строками:

Этот код добавляет в лавку торговца мечами две возможности:

как обратиться к скрипту на объекте unity

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

Интеграция с UI

Теперь нужно заставить работать UI. Наша цель заключается в отображении соответствующих данных Sword Data при нажатии на каждый меч.

Ссылки UI

Перед обновлением UI необходимо получить ссылку на каждый элемент UI. Начнём с создания нового скрипта под названием SwordMerchant.cs и добавления в этот новый скрипт следующего кода:

С помощью этого кода мы добавили следующее:

как обратиться к скрипту на объекте unity

Слушатели и отклики UI

У всех мечей есть событие, на которое может подписаться UI с помощью скрипта GameEventListener. Добавьте GameEventListener для каждого события OnSwordSelected к GameObject SwordMerchantCanvas:

как обратиться к скрипту на объекте unity

Как вы могли заметить, у нашего Game Event Listener есть два поля: событие Game Event, которое он слушает, и отклик, который вызывается при генерации Game Event.

В нашем случае отклик будет обновлять UI. Добавьте в скрипт SwordMerchant.cs следующий метод:

С помощью нашего нового метода мы можем добавить отклик к каждому GameEventListener.

Для каждого добавляемого отклика необходимо в качестве значения поля None (Object) ссылку на наш игровой объект SwordMerchantCanvas. После этого выберем SwordMerchant.UpdateDisplayUI из раскрывающегося меню справа от раскрывающегося списка Runtime Only.

Будьте внимательны и используйте правильный ассет Sword Data для каждого события OnSwordSelected.

как обратиться к скрипту на объекте unity

Теперь мы можем запустить игру, нажать на меч и увидеть, что UI обновился соответствующим образом!

как обратиться к скрипту на объекте unity

Поскольку мы используем Game Events, то можно просто SwordMerchantCanvas, и всё по-прежнему будет работать, только без UI. Это значит, что префабы мечей отделены от SwordMerchantCanvas.

Куда двигаться дальше?

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

Хотите больше узнать о Unity? Посмотрите нашу серию видео по Unity или прочитайте туториалы по Unity.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *