Найти все скрипты в сцене? [РЕШЕНО]
Найти все скрипты в сцене? [РЕШЕНО]
Доброго времени суток!
Подскажите как можно найти все скрипты в сцене? Зачатки разума подсказывают мне, что сгодится вот это FindObjectsOfType, но я никак не могу понять какой тип у скриптов?! То есть получается найти все кроме скриптов. Заранее благодарен.
Да пребудет с Вами Великий Коннект!
Последний раз редактировалось formurik 30 мар 2012, 17:50, всего редактировалось 1 раз.
-
formurik - UNIт
- Сообщения: 73
- Зарегистрирован: 31 мар 2011, 14:35
Re: Найти все скрипты в сцене?
Good1101 30 мар 2012, 17:42
По идее так можно собрать ссылки на все компоненты одного типа на сцене в массив
Используется csharp
Object[] GO = FindObjectsOfType(typeof(mySkript));
Хотя я не пробовал, нужно тестить.
-
Good1101 - Адепт
- Сообщения: 1100
- Зарегистрирован: 17 ноя 2011, 14:07
-
- ICQ
Re: Найти все скрипты в сцене? [РЕШЕНО]
formurik 30 мар 2012, 17:51
Тип MonoBehaviour очень даже подошел. Всем спасибо.
-
formurik - UNIт
- Сообщения: 73
- Зарегистрирован: 31 мар 2011, 14:35
Re: Найти все скрипты в сцене? [РЕШЕНО]
gate1 02 апр 2012, 12:54
Antares Browser позволяет просмотреть все скрипты которые используются в сцене
-
gate1 - UNITрон
- Сообщения: 198
- Зарегистрирован: 27 дек 2011, 22:19
- Откуда: Минск
Вернуться в Скрипты
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 11
Introduction — What we are going to do and why
In this article we are going to see a method that will allow us to find a COMPONENT of a specific type in Unity from a Script, for example to find a component type AudioSource, Collider or even a Script that we have created and assigned to a GameObject. The purpose of that is to have the reference of that component inside our Script and to be able to use it according to our needs. For example if we want to call a function that is defined in another Script we are going to need the reference of the instance of that other Script to be able to do it.
The method that we are going to see consists of using a code instruction that checks each GameObject of the hierarchy and its components until it finds the component of the type that we indicate, if there is a component of that type present in the scene the instruction will return it as the execution result and we will be able to store that component in a variable or to use it immediately to execute some simple action on the component that we found. If on the other hand there is no component of that type in any GameObject of the scene, the instruction will return Null and that could lead to an error of type NullReferenceException.
In the following video we see how to implement this method to find a component that is unique in the scene
After finding that scene component we use it to reference its GameObject because that is the idea of the video series, but this part is not necessary, you can use the component for whatever you need.
When is this method useful?
- This method is effective when the component we are looking for is unique in the scene, if there is more than one component of the same type there is no guarantee of finding precisely the one we are looking for.
- It is recommended to use this method in some initialization function like Awake or Start.
- It is not recommended to use this method inside update functions like Update because they imply to traverse in the worst case the whole hierarchy of the scene. Unless the program flow is somehow controlled so that the instruction is executed only once.
- If the component you want to find is going to be used more than once, it is advisable to find it once and store it in a global variable so that it can be used as many times as necessary.
Detailed procedure of finding a component from the scene through code
Initial conditions
We start from a Script called «FindReferenceOfAnObject» in which we are going to find the reference of a certain GameObject that is in the scene in Unity, inside the Script we will use that reference to print its name in console with the instruction of the line 13 of the figure 1.
The hierarchy of the scene that we are going to use is composed by the GameObjects that are shown in figure 2, the object «Script-GameObject» is the one that has the Script in figure 1 assigned and it is the one that will be in charge of finding the references, in figure 3 you can see the inspector of this GameObject, where the Script is assigned.
The «GDT (Object to Find)» object seen in figure 2 is the object we want to find from the script, so if we succeed we should see the name of this object printed on the console.
Find the reference of a GameObject that has a specific component
If we know that the GameObject we are interested in finding has a specific component assigned to it, such as a «Camera», «Rigidbody», «AudioSource» component or a script we have created ourselves, we can use that knowledge to find the GameObject reference.
I will create a script called «SomeScript» and assign it to the GameObject we want to find, as shown in figures 4 and 5.
Using the instruction «FindObjectOfType<T>()», where T is the type of object we are looking for (in our case it is «SomeScript» type), we can find the reference of the «SomeScript» instance that is assigned to that GameObject, then using the dot operator we can access the GameObject to which that Script is assigned.
The instruction that does all this can be seen in line 20 of figure 6.
When this instruction is executed, Unity will check all the objects in the hierarchy and each one of its components until it finds a «SomeScript» type object, when it finds it it returns it as a result, but since we are interested in the GameObject to which that Script is assigned, we use the dot operator and access the «gameObject» field. If there is no object that has the «SomeScript» component assigned to it we will have a null reference error because we are using the «objectToFind» field in line 22 of figure 6.
To keep in mind, if we have more than one GameObject that has assigned the component we are looking for, Unity will return the first component that it finds in its register, in this case ambiguities could arise, we could obtain the reference of a different object to the one we want.
Рассмотрим, как в Unity на языке C# получать доступ из одного скрипта к переменным и функциям других скриптов.
Юнити: Как обратиться к другому скрипту на том же объекте
GetComponent<DrygoiScript>().peremennayaScripta = 5;
Эта «команда» обращается к другому скрипту, который в виде компонента висит на том же объекте, что и скрипт, где вы это пишете. У этого скрипта есть переменная с именем peremennayaScripta, ей присваивается значение 5. Так можно обращаться к любым компонентам вашего игрового объекта, начиная от ваших скриптов, висящих на нем, и заканчивая обычными юнитивскими компонентами — Rigitbody, Animator, Transform и прочими.
Unity: Как получить ссылку на другой скрипт с одного объекта
Но вы можете не писать каждый раз «команду» GetComponent<>, а создать переменную для ссылки на компонент. Пишете:
DrygoiScript peremennayaSsilkaNaDrygoiScript = GetComponent<DrygoiScript>();
Вы тут сначала создали переменную с именем peremennayaSsilkaNaDrygoiScript и тип переменной DrygoiScript (что означает, что туда можно поместить только ссылку на DrygoiScript, но не на любой другой скрипт).
Потом вы через знак «=» присвоили этой переменной ссылку на DrygoiScript, который висит на том же объекте, что и этот скрипт с кодом.
Теперь вы можете написать:
peremennayaSsilkaNaDrygoiScript.peremennayaScripta = 5;
Через peremennayaSsilkaNaDrygoiScript произойдет обращение к тому скрипту (это аналогично GetComponent<DrygoiScript>()), и его переменная peremennayaScripta установится в значение 5.
Unity3d: как получить ссылку на другой объект
На другом объекте может висеть нужный вам скрипт, и вы хотите изменить его переменные или вызвать его функцию из другого скрипта? Тогда сначала нужно получить ссылку на него. Для этого создаете переменную в исходном скрипте:
public GameObject ssilkaNaObject;
Тут вы создали публичную переменную (теперь она будет видна в инспекторе) с типом GameObject (это базовый тип для любого объекта на сцене) и именем ssilkaNaObject. Теперь в инспектор вы можете перетянуть в нее нужный вам объект. Но надо еще получить ссылку на конкретный компонент (скрипт или еще что-либо навешанное на него) этого объекта. Например, на объекте висит скрипт с именем DrygoiScript, и вы хотите получить к нему доступ:
ssilkaNaObject.GetComponent<DrygoiScript>().peremennayaScripta = 5;
Тут вы по ссылке ssilkaNaObject обращаетесь к объекту, который перетянули в инспекторе в переменную ssilkaNaObject, и далее обращаетесь к конкретному компоненту GetComponent<DrygoiScript>(), это нужный вам скрипт, и меняете у этого скрипта переменную под названием peremennayaScripta на 5. Аналогично с вызовом какой-либо функций:
ssilkaNaObject.GetComponent<DrygoiScript>().MyFuction();
Тут вы вызвали функцию с именем MyFuction() в скрипте DrygoiScript, который висит на ssilkaNaObject.
Юнити: как кешировать ссылку на ваш скрипт
Но GetComponent<> ресурсозатратная операция, поэтому лучше сразу создать переменную, чтобы положить туда ссылку на конкретный компонент (ваш скрипт). Ссылку на объект мы уже получили, и она называется ssilkaNaObject, но не получили ссылку на скрипт DrygoiScript, поэтому и приходится каждый раз писать GetComponent<DrygoiScript>().
DrygoiScript peremennayaSsilkaNaDrygoiScript = ssilkaNaObject.GetComponent<DrygoiScript>();
Теперь переменная peremennayaSsilkaNaDrygoiScript будет содержать ссылку на ваш скрипт, который висит на объекте, на который ссылается ssilkaNaObject. И можно без всяких GetComponent писать:
peremennayaSsilkaNaDrygoiScript.peremennayaScripta = 5; // изменение значения переменной в другом скрипте peremennayaSsilkaNaDrygoiScript.MyFuction(); // вызов функции другого скрипта
Это называется кеширование. Мы с вами закешировали, как сам объект, на котором скрипт, так и ссылку на скрипт. Грубо говоря — кеширование это создание ссылки на нужную вещь, по которой потом можно обращаться к объекту, чтобы не приходилось каждый раз его искать заново.
Юнити3Д: как получить доступ к объекту из другого скрипта
До этого мы нужный нам объект переносили вручную через инспектор Unity в переменную ssilkaNaObject , но получить к нему доступ из кода можно несколькими способами.
public GameObject ssilkaNaObject; // не забывайте создавать переменную, которая будет ссылкой на объект ssilkaNaObject = GameObject.Find("ИмяОбъектаПоИерархии"); // поиск объекта по имени
Тут в переменную ssilkaNaObject мы заносим то, что найдет компьютер по имени в иерархии сцены Unity. Минус в том, что придется запоминать, что переименовывать объект нельзя.
ssilkaNaObject = GameObject.FindGameObjectWithTag("Player"); // поиск объекта по тегу
Так мы получим ссылку на первый объект, который найдет компьютер по тегу Player (задается в инспекторе). Если объектов несколько с одним тегом, то в ссылку компьютер положит первый попавшийся.
Советы
Все операции, когда вы переменной присваиваете ссылку на объект или компонент (скрипт) проводят, как правило, в методе Start. Сами переменные создаются вне методов, чтобы они были доступны по всему скрипту, а не были локальными в каком-то методе. А значения им присваиваются в методе Start, который срабатывает когда запускается сцена, тогда Unity3d и найдет нужный объекты, и запишет в ваши переменные ссылки на них. Например:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class TestPoiskObjectov : MonoBehaviour { // это место вне каких-либо методов public GameObject ssilkaNaObject; // не забывайте создавать переменную, которая будет ссылкой на объект public DrygoiScript peremennayaSsilkaNaDrygoiScript; // переменная для ссылки на конкретный скрипт void Start () { // поиск объекта по имени ssilkaNaObject = GameObject.Find("ИмяОбъектаПоИерархии"); // получение ссылки на компонент с другого объекта DrygoiScript peremennayaSsilkaNaDrygoiScript = ssilkaNaObject.GetComponent<DrygoiScript>(); } void Update () { } }
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEditor; | |
using System.Collections.Generic; | |
using UnityEngine.SceneManagement; //3 | |
public class SelectGameObjectsWithMissingScripts : Editor | |
{ | |
[MenuItem(«Tools/WPAG Utilities/Select GameObjects With Missing Scripts«)] | |
static void SelectGameObjects() | |
{ | |
//Get the current scene and all top-level GameObjects in the scene hierarchy | |
Scene currentScene = SceneManager.GetActiveScene(); | |
GameObject[] rootObjects = currentScene.GetRootGameObjects(); | |
List<Object> objectsWithDeadLinks = new List<Object>(); | |
foreach (GameObject g in rootObjects) | |
{ | |
//Get all components on the GameObject, then loop through them | |
Component[] components = g.GetComponents<Component>(); | |
for (int i = 0; i < components.Length; i++) | |
{ | |
Component currentComponent = components[i]; | |
//If the component is null, that means it’s a missing script! | |
if (currentComponent == null) | |
{ | |
//Add the sinner to our naughty-list | |
objectsWithDeadLinks.Add(g); | |
Selection.activeGameObject = g; | |
Debug.Log(g + « has a missing script!«); | |
break; | |
} | |
} | |
} | |
if (objectsWithDeadLinks.Count > 0) | |
{ | |
//Set the selection in the editor | |
Selection.objects = objectsWithDeadLinks.ToArray(); | |
} | |
else | |
{ | |
Debug.Log(«No GameObjects in ‘« + currentScene.name + «‘ have missing scripts! Yay!«); | |
} | |
} | |
} |
Загрузка…