Tanoda
GameObjectSearcher.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Reflection;
6using UnityEngine;
7
9{
13 public class GameObjectSearcher
14 {
15 private List<GameObject> _cachedRootGameObjects;
16 private List<GameObject> _searchResults;
17
18 public static IEnumerable<GameObject> FindAllRootGameObjects()
19 {
20 return Resources.FindObjectsOfTypeAll<Transform>()
21 .Where(t => t.parent == null)
22 .Select(x => x.gameObject);
23 }
24
25 public IEnumerable<GameObject> GetRootObjects()
26 {
27 if (_cachedRootGameObjects != null)
28 {
29 _cachedRootGameObjects.RemoveAll(o => o == null);
30 return _cachedRootGameObjects;
31 }
32 return Enumerable.Empty<GameObject>();
33 }
34
35 public IEnumerable<GameObject> GetSearchedOrAllObjects()
36 {
37 if (_searchResults != null)
38 {
39 _searchResults.RemoveAll(o => o == null);
40 return _searchResults;
41 }
42 return GetRootObjects();
43 }
44
45 public void Refresh(bool full, Predicate<GameObject> objectFilter)
46 {
47 if (_searchResults != null)
48 return;
49
50 if (_cachedRootGameObjects == null || full)
51 {
52 _cachedRootGameObjects = FindAllRootGameObjects().OrderBy(x => x.name, StringComparer.InvariantCultureIgnoreCase).ToList();
53 full = true;
54 }
55 else
56 {
57 _cachedRootGameObjects.RemoveAll(o => o == null);
58 }
59
60 if (UnityFeatureHelper.SupportsScenes && !full)
61 {
62 var newItems = UnityFeatureHelper.GetSceneGameObjects().Except(_cachedRootGameObjects).ToList();
63 if (newItems.Count > 0)
64 {
65 _cachedRootGameObjects.AddRange(newItems);
66 _cachedRootGameObjects.Sort((o1, o2) => string.Compare(o1.name, o2.name, StringComparison.InvariantCultureIgnoreCase));
67 }
68 }
69
70 if (objectFilter != null)
71 _cachedRootGameObjects.RemoveAll(objectFilter);
72 }
73
74 public void Search(string searchString, bool searchProperties)
75 {
76 if (string.IsNullOrEmpty(searchString))
77 _searchResults = null;
78 else
79 {
80 _searchResults = GetRootObjects()
81 .SelectMany(x => x.GetComponentsInChildren<Transform>(true))
82 .Where(x => x.name.Contains(searchString, StringComparison.InvariantCultureIgnoreCase) || x.GetComponents<Component>().Any(c => SearchInComponent(searchString, c, searchProperties)))
83 .OrderBy(x => x.name, StringComparer.InvariantCultureIgnoreCase)
84 .Select(x => x.gameObject)
85 .ToList();
86 }
87 }
88
89 public static bool SearchInComponent(string searchString, Component c, bool searchProperties)
90 {
91 if (c == null) return false;
92
93 var type = c.GetType();
94 if (type.Name.Contains(searchString, StringComparison.InvariantCultureIgnoreCase))
95 return true;
96
97 if (!searchProperties)
98 return false;
99
100 var nameBlacklist = new[] {"parent", "parentInternal", "root", "transform", "gameObject"};
101 var typeBlacklist = new[] {typeof(bool)};
102
103 foreach (var prop in type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
104 .Where(x => x.CanRead && !nameBlacklist.Contains(x.Name) && !typeBlacklist.Contains(x.PropertyType)))
105 {
106 try
107 {
108 if (prop.GetValue(c, null).ToString().Contains(searchString, StringComparison.InvariantCultureIgnoreCase))
109 return true;
110 }
111 catch { }
112 }
113 foreach (var field in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
114 .Where(x => !nameBlacklist.Contains(x.Name) && !typeBlacklist.Contains(x.FieldType)))
115 {
116 try
117 {
118 if (field.GetValue(c).ToString().Contains(searchString, StringComparison.InvariantCultureIgnoreCase))
119 return true;
120 }
121 catch { }
122 }
123
124 return false;
125 }
126 }
127}
UnityEngine.Component Component
Keeps track of root gameobjects and allows searching objects in the scene
void Search(string searchString, bool searchProperties)
void Refresh(bool full, Predicate< GameObject > objectFilter)
static IEnumerable< GameObject > FindAllRootGameObjects()
static bool SearchInComponent(string searchString, Component c, bool searchProperties)