forked from Shardstone/trail-into-darkness
203 lines
8.0 KiB
C#
203 lines
8.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
using Object = UnityEngine.Object;
|
|
|
|
namespace Jovian.Utilities {
|
|
public static class SceneUtility {
|
|
|
|
public static List<GameObject> FindGameObjectsInScene(this Scene scene, bool includeInactive = false, Func<GameObject, bool> predicate = null) {
|
|
if (scene.IsValid() == false)
|
|
{
|
|
Debug.LogError("Scene is invalid");
|
|
return null;
|
|
}
|
|
|
|
var list = new List<GameObject>();
|
|
GameObject[] sceneObjects = scene.GetRootGameObjects();
|
|
GameObject[] loadedObjects = FindDontDestroyOnLoadObjects();
|
|
GameObject[] combinedGameobjects = new GameObject[sceneObjects.Length + loadedObjects.Length];
|
|
sceneObjects.CopyTo(combinedGameobjects, 0);
|
|
loadedObjects.CopyTo(combinedGameobjects, sceneObjects.Length);
|
|
foreach (var rootObject in combinedGameobjects)
|
|
{
|
|
var allChildTransforms = rootObject.GetComponentsInChildren<Transform>(includeInactive);
|
|
var allGameObjects = allChildTransforms.Select(transform => transform.gameObject);
|
|
if (predicate != null)
|
|
{
|
|
allGameObjects = allGameObjects.Where(predicate);
|
|
}
|
|
|
|
list.AddRange(allGameObjects);
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
public static List<GameObject> FindGameObjectsInActiveScene(bool includeInactive = false, Func<GameObject, bool> predicate = null)
|
|
=> FindGameObjectsInScene(SceneManager.GetActiveScene(), includeInactive, predicate);
|
|
|
|
// Adding support for finding objects not in the main scenes but in DontDestroyOnLoad
|
|
// From https://forum.unity.com/threads/editor-script-how-to-access-objects-under-dontdestroyonload-while-in-play-mode.442014/#post-3570916
|
|
private static GameObject[] FindDontDestroyOnLoadObjects() {
|
|
if (!Application.isPlaying)
|
|
{
|
|
return new GameObject[] { }; // return an empty array as this method creates issues in edit mode
|
|
}
|
|
|
|
GameObject temp = null;
|
|
try
|
|
{
|
|
temp = new GameObject();
|
|
Object.DontDestroyOnLoad(temp);
|
|
UnityEngine.SceneManagement.Scene dontDestroyOnLoad = temp.scene;
|
|
Object.DestroyImmediate(temp);
|
|
temp = null;
|
|
|
|
return dontDestroyOnLoad.GetRootGameObjects();
|
|
}
|
|
finally
|
|
{
|
|
if (temp != null)
|
|
Object.DestroyImmediate(temp);
|
|
}
|
|
}
|
|
|
|
public static List<TComponent> FindComponentsInScene<TComponent>(this Scene scene, bool includeInactive = false) where TComponent : Component {
|
|
if (scene.IsValid() == false)
|
|
{
|
|
Debug.LogError("Scene is invalid");
|
|
return null;
|
|
}
|
|
|
|
var list = new List<TComponent>();
|
|
|
|
foreach (var rootObject in scene.GetRootGameObjects())
|
|
{
|
|
list.AddRange(rootObject.GetComponentsInChildren<TComponent>(includeInactive));
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
public static List<Component> FindComponentsInScene(this Scene scene, Type componentType, bool includeInactive = false) {
|
|
if (scene.IsValid() == false)
|
|
{
|
|
Debug.LogError("Scene is invalid");
|
|
return null;
|
|
}
|
|
|
|
var list = new List<Component>();
|
|
foreach (GameObject rootObject in scene.GetRootGameObjects())
|
|
{
|
|
list.AddRange(rootObject.GetComponentsInChildren(componentType, includeInactive));
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
public static List<TComponent> FindComponentsInActiveScene<TComponent>(bool includeInactive = false) where TComponent : Component
|
|
=> FindComponentsInScene<TComponent>(SceneManager.GetActiveScene(), includeInactive);
|
|
|
|
public static List<Component> FindComponentsInActiveScene(Type componentType, bool includeInactive = false)
|
|
=> FindComponentsInScene(SceneManager.GetActiveScene(), componentType, includeInactive);
|
|
|
|
public static List<TComponent> FindComponentsInAllScenes<TComponent>(bool includeInactive = false) where TComponent : Component {
|
|
List<TComponent> allComponents = new();
|
|
for (int i = 0, c = SceneManager.sceneCount; i < c; i++)
|
|
{
|
|
allComponents.AddRange(FindComponentsInScene<TComponent>(SceneManager.GetSceneAt(i), includeInactive));
|
|
}
|
|
|
|
return allComponents;
|
|
}
|
|
|
|
public static TComponent FindComponentInScene<TComponent>(this Scene scene, bool includeInactive = false) where TComponent : Component {
|
|
if (scene.IsValid() == false)
|
|
{
|
|
Debug.LogError("Scene is invalid");
|
|
return null;
|
|
}
|
|
|
|
var list = new List<TComponent>();
|
|
|
|
foreach (var rootObject in scene.GetRootGameObjects())
|
|
{
|
|
list.AddRange(rootObject.GetComponentsInChildren<TComponent>(includeInactive));
|
|
}
|
|
|
|
return list.FirstOrDefault();
|
|
}
|
|
|
|
public static Component FindComponentInScene(this Scene scene, Type componentType, bool includeInactive = false) {
|
|
if (scene.IsValid() == false)
|
|
{
|
|
Debug.LogError("Scene is invalid");
|
|
return null;
|
|
}
|
|
|
|
var list = new List<Component>();
|
|
|
|
foreach (GameObject rootObject in scene.GetRootGameObjects())
|
|
{
|
|
list.AddRange(rootObject.GetComponentsInChildren(componentType, includeInactive));
|
|
}
|
|
|
|
return list.FirstOrDefault();
|
|
}
|
|
|
|
public static TComponent FindComponentInActiveScene<TComponent>(bool includeInactive = false) where TComponent : Component
|
|
=> FindComponentInScene<TComponent>(SceneManager.GetActiveScene(), includeInactive);
|
|
|
|
public static Component FindComponentInActiveScene(Type componentType, bool includeInactive = false)
|
|
=> FindComponentInScene(SceneManager.GetActiveScene(), componentType, includeInactive);
|
|
|
|
public static TComponent FindComponentInAllScenes<TComponent>(bool includeInactive = false) where TComponent : Component
|
|
=> FindComponentsInAllScenes<TComponent>(includeInactive).FirstOrDefault();
|
|
|
|
|
|
public static GameObject FindGameObject(string nameQuery) {
|
|
char delimiter = '/';
|
|
string[] querySegments = nameQuery.Split(delimiter);
|
|
|
|
return FindGameObjectsInActiveScene(true, (gameObject) => {
|
|
int queryIndex = querySegments.Length - 1;
|
|
Transform compareTransform = gameObject.transform;
|
|
do
|
|
{
|
|
if (compareTransform != null && compareTransform.name.Equals(querySegments[queryIndex]))
|
|
{
|
|
compareTransform = compareTransform.parent;
|
|
queryIndex--;
|
|
}
|
|
// if compare is null and string is null that means the first query segment was /, so that's the root element - then our parent MUST be null
|
|
else if (compareTransform == null && string.IsNullOrEmpty(querySegments[queryIndex]))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
} while (queryIndex >= 0);
|
|
|
|
return true;
|
|
}).FirstOrDefault();
|
|
}
|
|
|
|
private static Transform GetChildWithName(this Transform transform, string childName) {
|
|
foreach (Transform child in transform.transform)
|
|
{
|
|
if (child.name.Equals(childName))
|
|
{
|
|
return child;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
}
|
|
} |