В Unity есть средство для маркировки объектов с помощью тэгов. Тэг это текстовое имя, по которому можно искать и работать с объектами сцены.
Пользователь может создать сколько угодно тэгов, но так же есть встроенные по умолчанию:
- Respawn
- Finish
- EditorOnly
- MainCamera
- Player
- GameConroller
Создать или выбрать теги можно выбрав любой GameObject и в инспекторе используя поле Tag:
Теперь пример использования.
Нам понадобится тэг “Menu”, на скриншотах выше он уже создан, так что с его созданием Вы справитесь.
Далее я предлагаю рассмотреть три скрипта, на основе который мы должны будем собрать сцену.
MainMenu.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | using UnityEngine; public class MainMenu : MonoBehaviour { public void OnGUI() { // позиция меню Rect areaPos = new Rect(Screen.width / 2f - 60f, Screen.height / 2f - 100f, 120, 200); // создаем стиль с выравниванием по центру GUIStyle label = new GUIStyle(GUI.skin.label); label.alignment = TextAnchor.MiddleCenter; // область со стилем window GUILayout.BeginArea(areaPos, GUI.skin.window); { GUILayout.Space(-20); // рисуем название меню GUILayout.Label("Main Menu", label); GUILayout.Space(10); // кнопка "Start Game" if (GUILayout.Button("Start Game", GUILayout.Height(25))) { // активируем меню StartGame ActivateMenu("StartGame"); } GUILayout.Space(8); // кнопка "Options" if (GUILayout.Button("Options", GUILayout.Height(25))) { // активируем меню Options ActivateMenu("Options"); } GUILayout.Space(8); // кнопка выхода if (GUILayout.Button("Quit", GUILayout.Height(25))) { Application.Quit(); } } GUILayout.EndArea(); } // с помощью этой функции будем активировать меню public static void ActivateMenu(string menuName) { // получаем все объекты сцены, комеченные тэгом Menu GameObject[] menus = GameObject.FindGameObjectsWithTag("Menu"); // перебираем foreach (GameObject menu in menus) { // если имя совпадает с указанным, то активируем компоненты объекта, если нет - деактивируем bool active = menu.name == menuName; foreach (MonoBehaviour behaviour in menu.GetComponents()) { behaviour.enabled = active; } } } } |
OptionsMenu.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | using System; using UnityEngine; public class OptionsMenu : MonoBehaviour { public void OnGUI() { Rect areaPos = new Rect(Screen.width / 2f - 60f, Screen.height / 2f - 125f, 120, 250); // создаем стиль с выравниванием по центру GUIStyle label = new GUIStyle(GUI.skin.label); label.alignment = TextAnchor.MiddleCenter; GUILayout.BeginArea(areaPos, GUI.skin.window); { GUILayout.Space(-20); // название меню GUILayout.Label("Options", label); GUILayout.Space(5); GUILayout.Label("Graphics Level:", label); GUILayout.Space(8); // кнопки выбора качества foreach (QualityLevel qualityLevel in Enum.GetValues(typeof (QualityLevel))) { // цвет кнопки в зависимости что выбрано GUI.color = (QualitySettings.currentLevel == qualityLevel) ? Color.red : Color.white; // кадая кнопка выбирает качество if (GUILayout.Button(qualityLevel.ToString())) { QualitySettings.currentLevel = qualityLevel; } } GUI.color = Color.white; GUILayout.Space(12); // кнопка Back if (GUILayout.Button("Back", GUILayout.Height(25))) { MainMenu.ActivateMenu("MainMenu"); } } GUILayout.EndArea(); } } |
LoadingGameMenu.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | using UnityEngine; using System.Collections; public class LoadingGameMenu : MonoBehaviour { // строка с прогрессом private string _progress = "Loading"; // флаг загрузки private bool _loaded; // при активации компонента public void OnEnable() { StartCoroutine(ProgressBarUpdater()); } // сопрограмма загрузки public IEnumerator ProgressBarUpdater() { for (int i = 0; i < 9; i++) { _progress += "."; yield return new WaitForSeconds(1); } _loaded = true; } // вывод GUI части public void OnGUI() { Rect pos = new Rect(Screen.width / 2f - 60f, Screen.height / 2f - 10f, 120, 20); if (!_loaded) { // отображаем процесс загрузки GUI.Label(pos, _progress); } else { if(GUI.Button(pos, "Play")) { // старт игры } } } } |
Обратите внимание на статическую функцию ActivateMenu первого скрипта. Эта функция принимает имя объекта сцены на который происходит переключение. Из остальных скриптов так же используется эта функция. Она ведет себя следующим образом: 1) находит все объекты помеченные тэгом "Menu"; 2) по имени объекта определяет что нужно сделать с компонентами объекта – включить или выключить; 3) собственно включает и выключает компоненты.
Для того чтобы активировать например меню Options мы передаем этой функции его имя и она оставляет включенными компоненты только на объекте с именем Options.
Попробуем собрать сцену:
- Создайте следующую иерархию объектов их пустых GameObject’ов:
- Назначьте соответствующие скрипты объектам меню и так же назначьте им тэг “Menu”.
Заметьте что, включенным должен быть только один скрипт меню (в нащем случае MainMenu). - Можно протестировать сцену.
Я не буду описывать работу скриптов, т.к. там хватает комментариев, а остальное должно быть понятно
Иногда одного тэга на объекта не хватает, но в стандартных средствах юнити нет поддержки назначения нескольких тэгов на один объект. Данная проблема решена в проекте Antares, о котором Вы уже наверное много раз слышали. Скачать его можно здесь.
Удачи!
11 комментариев на «Работа с тэгами»
Ваш отзыв
Вы должны войти, чтобы оставлять комментарии.
18 Ноя 2010 в 13:52
Кажется я нашел несколько неточностей.
1. В листинге LoadingGameMenu.cs фигурируют HTML сущности: " и <
2. Unity 3.1 ругается:
Assets/MainMenu.cs(64,54): error CS0411: The type arguments for method `UnityEngine.GameObject.GetComponents()’ cannot be inferred from the usage. Try specifying the type arguments explicitly
знаний не хватает, что бы исправить.
10 Окт 2011 в 3:56
“http://en.visors.ru/?p=3936&lol= north@bwgxs3.jump“>.…
спс
…
08 Дек 2011 в 20:10
anger@bwrit5.garden” rel=”nofollow”>.…
сэнкс за инфу
…
09 Дек 2011 в 17:27
…
спасибо за инфу
…
10 Дек 2011 в 2:11
спасибо за инфу
…
10 Дек 2011 в 16:26
спс за инфу
…
11 Дек 2011 в 8:50
сэнкс за инфу
…
11 Дек 2011 в 21:04
сэнкс за инфу
…
25 Фев 2012 в 15:31
Если возникает ошибка
“error CS0411: The type arguments for method `UnityEngine.GameObject.GetComponents()’ cannot be inferred from the usage. Try specifying the type arguments explicitly”,
то можно попробовать следующее: в foreach`е поменять
menu.GetComponents()
на
menu.GetComponents()
25 Фев 2012 в 15:35
К последнему сообщению исправление:
поменять на
menu.GetComponents”MonoBehaviour”()
Вместо кавычек должны быть теги (< и >)
23 Дек 2013 в 14:22
lewisohn@dora.progandist” rel=”nofollow”>.…
спс….