В сцене есть неактивный элемент. Как его найти программно ? Я пробовал искать по тегу просто искать возвращает null как будто его и нету.
GameObject go1 = GameObject.FindGameObjectsWithTag("tag"); // null
GameObject go2 = GameObject.Find("P_Complete"); // null
задан 17 фев 2019 в 12:05
GameObject.Find
Finds a GameObject by name and returns it.
This function only returns active GameObjects. If no GameObject with
name can be found, null is returned. If name contains a ‘/’ character,
it traverses the hierarchy like a path name.
public static class GameObjectExtension {
public static Object Find(string name, System.Type type) {
Object[] objects = Resources.FindObjectsOfTypeAll(type);
foreach(var obj in objects) {
if(obj.name == name) {
return obj;
}
}
return null;
}
public static GameObject Find(string name) {
return Find(name, typeof(GameObject)) as GameObject;
}
}
Использование:
void TestMethod() {
GameObject obj = GameObjectExtension.Find("GameObject");
if (obj) {
obj.SetActive(true);
}
}
P.S.
Данный подход очень, очень и еще раз очень медленный. Использовать его нужно только в самых крайних случаях. Сама проблема поиска неактивных объектов зачастую возникает из-за неправильной архитектуры, такие проблемы обычно решаются через ручную установку референсов.
ответ дан 17 фев 2019 в 12:43
1
Эта функция возвращает любой объект Юнити, который загружен включая префабы, текстуры итд, в том числе и отключенные геймобджекты
Resources.FindObjectsOfTypeAll<T>()
ответ дан 17 фев 2019 в 12:35
Stranger in the QStranger in the Q
56k10 золотых знаков79 серебряных знаков133 бронзовых знака
For newer Unity versions this answer provides probably a better solution!
First of all
In general any usage of Find
or it’s variants should be avoided.
Actually they are never really required but only a “hot-fix” used to cover an implementation “laziness”.
Usually from the beginning storing and passing on required references is always the better approach.
Especially in your case you seem to have a fix amount of objects so you could probably already reference them all in a certain “manager” component and store them in a list or array (them you can get a reference by index) or even a Dictionary<string, GameObject>
(then you can also get the according reference by name – you can find an example below).
Workarounds
There are alternative solutions (FindObjectsWithTag
, FindObjectsOfType
) but it will always be quite expensive (though most of the Find
variants are expensive anyway).
You could e.g. also “manually” iterate through all objects in the scene using Scene.GetRootGameObjects
Returns all the root game objects in the Scene.
And then search through them until you find your object. This way you get also inactive GameObject.
public static GameObject Find(string search)
{
var scene = SceneManager.GetActiveScene();
var sceneRoots = scene.GetRootGameObjects();
GameObject result = null;
foreach(var root in sceneRoots)
{
if(root.name.Equals(search)) return root;
result = FindRecursive(root, search);
if(result) break;
}
return result;
}
private static GameObject FindRecursive(GameObject obj, string search)
{
GameObject result = null;
foreach(Transform child in obj.transform)
{
if(child.name.Equals(search)) return child.gameObject;
result = FindRecursive (child.gameObject, search);
if(result) break;
}
return result;
}
But ofcourse this should be strongly avoided and the usage of such deep searches reduced to a minimum!
What I would do
Another way – in my eyes the best approach here – could be to have a certain component attached to all your objects and actually store all the references once as said before in a dictionary like e.g.
public class FindAble : MonoBehaviour
{
private static readonly Dictionary<string, GameObject> _findAbles = new Dictionary<string, GameObject>();
public static GameObject Find(string search)
{
if(!_findAbles.ContainsKey(search)) return null;
return _findAbles[search];
}
private IEnumerator Start()
{
// Wait one frame
// This makes it possible to spawn this object and
// assign it a different name before it registers
// itself in the dictionary
yield return null;
if(_findAbles.ContainsKey(name))
{
Debug.LogError($"Another object with name /"{name}/" is already registered!", this);
yield break;
}
_findAbles.Add(name, gameObject);
}
private void OnDestroy ()
{
if(_findAbles.ContainsKey(name))
{
_findAbles.Remove(name);
}
// Optionally clean up and remove entries that are invalid
_findAbles = _findAbles.Where(kvp => kvp.Value).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}
}
and then use it like
var obj = FindAble.Find("SomeName");
if(obj)
{
// ...
}
Also for this the component would need to be enabled at least once so Start
is called.
Again an alternative would be to have instead a
public void Initialize(string newName)
{
if(_findAbles.ContainsKey(name))
{
Debug.LogError($"Another object with name /"{name}/" is already registered!", this);
return;
}
name = newName;
_findAbles.Add(name, gameObject);
}
which you could call also after e.g. spawning an inactive object.
Как найти выключенный объект на сцене и включить?
Как найти выключенный объект на сцене и включить?
Собственно, тема раскрыта в названии. Создан private GameObject и внутри класса я должен его найти и включить. Скрин прилагается
- pesiik
- UNITрон
- Сообщения: 223
- Зарегистрирован: 01 авг 2015, 11:46
Re: Как найти выключенный объект на сцене и включить?
GeoGraf 07 окт 2015, 16:42
Насколько я знаю найти выключенный объект невозможно.
Если Вы его создаете программно, то перед выключением сохраните на него ссылку.
Если он должен быть на сцене изначально, то сделайте его активным, а при старте сохраните ссылку и выключите его.
-
GeoGraf - UNITрон
- Сообщения: 341
- Зарегистрирован: 10 сен 2014, 16:53
- Откуда: Тверь, Россия
Re: Как найти выключенный объект на сцене и включить?
pesiik 07 окт 2015, 16:47
GeoGraf писал(а):Насколько я знаю найти выключенный объект невозможно.
Если Вы его создаете программно, то перед выключением сохраните на него ссылку.
Если он должен быть на сцене изначально, то сделайте его активным, а при старте сохраните ссылку и выключите его.
Это понятно. дело в том, что у меня около 300 объектов в одной точке. и мне надо включать камеру и один из объектов по нажатию ui кнопки. эт придется все 300 объектов прописывать))) че т не крут. мож есть способ?
- pesiik
- UNITрон
- Сообщения: 223
- Зарегистрирован: 01 авг 2015, 11:46
Re: Как найти выключенный объект на сцене и включить?
GeoGraf 07 окт 2015, 16:58
Если объект удочерен, тогда так:
Метод:
Используется csharp
public static GameObject FindObject(this GameObject parent, string name)
{
Transform[] trs= parent.GetComponentsInChildren(typeof(Transform), true);
foreach(Transform t in trs){
if(t.name == name){
return t.gameObject;
}
}
return null;
}
Использование метода:
Используется csharp
GameObject obj = parentObject.FindObject(“MyObject”);
-
GeoGraf - UNITрон
- Сообщения: 341
- Зарегистрирован: 10 сен 2014, 16:53
- Откуда: Тверь, Россия
Re: Как найти выключенный объект на сцене и включить?
pesiik 07 окт 2015, 17:09
GeoGraf писал(а):Если объект удочерен, тогда так:
Метод:Используется csharp
public static GameObject FindObject(this GameObject parent, string name)
{
Transform[] trs= parent.GetComponentsInChildren(typeof(Transform), true);
foreach(Transform t in trs){
if(t.name == name){
return t.gameObject;
}
}
return null;
}Использование метода:
Используется csharp
GameObject obj = parentObject.FindObject(“MyObject”);
Ооо спасибо! возьму на вооружение. Но я другой хитростью воспользовался. Просто все объекты включил и вынес за пределы камеры. И определенный перемещается в центр камеры. А скрпит обзора повесил на пустой объект в центре камеры
- pesiik
- UNITрон
- Сообщения: 223
- Зарегистрирован: 01 авг 2015, 11:46
Re: Как найти выключенный объект на сцене и включить?
Linebeck 08 окт 2015, 08:54
pesiik писал(а):Собственно, тема раскрыта в названии. Создан private GameObject и внутри класса я должен его найти и включить. Скрин прилагается
Объект включить нельзя. Зато можно компонет объекта включить/выключить, renderer например.
-
Linebeck - UNец
- Сообщения: 48
- Зарегистрирован: 08 июн 2015, 09:49
Re: Как найти выключенный объект на сцене и включить?
Zaicheg 09 окт 2015, 00:12
Linebeck писал(а):
Выключает объект.
У меня такая же проблема дома: выключатели света есть, а включателей нет. Я сдуру половину ламп выключил, что теперь делать — не знаю.
-
Zaicheg - Адепт
- Сообщения: 3024
- Зарегистрирован: 19 июн 2009, 15:12
- Откуда: Череповец
Re: Как найти выключенный объект на сцене и включить?
Vrz 09 окт 2015, 17:10
Linebeck писал(а):
Выключает объект.
false меняешь на true и он включается, у меня никаких проблем с этим нет.
Что касается первого поста, то вместо Instrument.gameObject.SetActive() должно быть Instrument.SetActive(true), на сколько я помню. И ещё надо проверить устанавливается ли объект вообще в Instrument (т.к. он запривачен, смотреть инспектор в режиме дебаг), а то ошибка в 25 строке подозрительна. При чём родительский объект тоже должен быть включён.
- Vrz
- UNец
- Сообщения: 3
- Зарегистрирован: 30 сен 2015, 15:18
Re: Как найти выключенный объект на сцене и включить?
Linebeck 10 окт 2015, 01:21
Vrz писал(а):
Linebeck писал(а):
Выключает объект.
false меняешь на true и он включается, у меня никаких проблем с этим нет.
Что касается первого поста, то вместо Instrument.gameObject.SetActive() должно быть Instrument.SetActive(true), на сколько я помню. И ещё надо проверить устанавливается ли объект вообще в Instrument (т.к. он запривачен, смотреть инспектор в режиме дебаг), а то ошибка в 25 строке подозрительна. При чём родительский объект тоже должен быть включён.
Ясно ,спасибо. У меня не включало год назад, приходилось через renderer работать, может уже пофиксили.
-
Linebeck - UNец
- Сообщения: 48
- Зарегистрирован: 08 июн 2015, 09:49
Вернуться в Почемучка
Кто сейчас на конференции
Сейчас этот форум просматривают: Yandex [Bot] и гости: 28
GameObject.Find
Finds a GameObject by name and returns it.
This function only returns active GameObjects. If no GameObject with
name can be found, null is returned. If name contains a ‘/’ character,
it traverses the hierarchy like a path name.
public static class GameObjectExtension {
public static Object Find(string name, System.Type type) {
Object[] objects = Resources.FindObjectsOfTypeAll(type);
foreach(var obj in objects) {
if(obj.name == name) {
return obj;
}
}
return null;
}
public static GameObject Find(string name) {
return Find(name, typeof(GameObject)) as GameObject;
}
}
Использование:
void TestMethod() {
GameObject obj = GameObjectExtension.Find("GameObject");
if (obj) {
obj.SetActive(true);
}
}
P.S.
Данный подход очень, очень и еще раз очень медленный. Использовать его нужно только в самых крайних случаях. Сама проблема поиска неактивных объектов зачастую возникает из-за неправильной архитектуры, такие проблемы обычно решаются через ручную установку референсов.
Uzist Сын моей мамы 187 / 130 / 60 Регистрация: 09.05.2020 Сообщений: 679 |
||||
1 |
||||
Найти неактивный объект на сцене29.04.2022, 20:48. Показов 787. Ответов 4 Метки unity (Все метки)
Здравствуйте, есть VictoryPanel, которая с самого начала неактивная.И при выполнении условия VictoryPanel становилась активной.Если что объект удочерён Пробовал так(взял с форума)
но выдало ошибки : ‘Object’ is an ambiguous reference between ‘UnityEngine.Object’ and ‘object’
0 |
vladpad92 18 / 11 / 7 Регистрация: 06.04.2022 Сообщений: 172 |
||||
29.04.2022, 21:42 |
2 |
|||
Добавлено через 46 секунд
0 |
UnityNub UNITY 75 / 48 / 28 Регистрация: 20.04.2022 Сообщений: 159 |
||||
29.04.2022, 23:08 |
3 |
|||
Сообщение было отмечено Uzist как решение РешениеUzist, вам проще оставлять Panel активной, а скрывать компонент Image. тогда панель будет легко находиться.
1 |
Сын моей мамы 187 / 130 / 60 Регистрация: 09.05.2020 Сообщений: 679 |
|
29.04.2022, 23:35 [ТС] |
4 |
vladpad92, не, мне не подходит такой способ, раньше я им пользовался,тно сцен стало много и этот способ перестал мне подходить Добавлено через 4 минуты
0 |
18 / 11 / 7 Регистрация: 06.04.2022 Сообщений: 172 |
|
30.04.2022, 09:58 |
5 |
Uzist, Тебе уже дали действенный способ, Убери галочку с Image в инспекторе, а потом включай через скрипт
0 |