1753 lines
42 KiB
C#
1753 lines
42 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
public class MonoBehaviourExtended : MonoBehaviour
|
|
{
|
|
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
|
|
protected class DependencyAttribute : PropertyAttribute
|
|
{
|
|
public string Of { get; set; }
|
|
|
|
public int Offset { get; set; }
|
|
|
|
public bool Optional { get; set; }
|
|
|
|
public DependencyAttribute()
|
|
{
|
|
}
|
|
|
|
public DependencyAttribute(int generationOffset)
|
|
{
|
|
Offset = generationOffset;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
string text = base.ToString();
|
|
return text.Remove(0, text.IndexOf('+') + 1);
|
|
}
|
|
}
|
|
|
|
protected class ComponentDependencyAttribute : DependencyAttribute
|
|
{
|
|
public ComponentDependencyAttribute(int generationOffset = 0)
|
|
: base(generationOffset)
|
|
{
|
|
}
|
|
}
|
|
|
|
protected class OwnComponentAttribute : ComponentDependencyAttribute
|
|
{
|
|
public OwnComponentAttribute(int generationOffset = 0)
|
|
: base(generationOffset)
|
|
{
|
|
}
|
|
}
|
|
|
|
protected class ComponentAttribute : ComponentDependencyAttribute
|
|
{
|
|
public ComponentAttribute(int generationOffset = 0)
|
|
: base(generationOffset)
|
|
{
|
|
}
|
|
}
|
|
|
|
protected class GlobalComponentAttribute : ComponentDependencyAttribute
|
|
{
|
|
}
|
|
|
|
protected class ReferenceComponentAttribute : ComponentDependencyAttribute
|
|
{
|
|
public bool DeepSearch { get; set; }
|
|
|
|
public ReferenceComponentAttribute(bool deepSearch = false)
|
|
{
|
|
DeepSearch = deepSearch;
|
|
}
|
|
}
|
|
|
|
protected class ChildComponentAttribute : ComponentDependencyAttribute
|
|
{
|
|
public bool SkipItself { get; set; }
|
|
|
|
public ChildComponentAttribute(int generationOffset = 0)
|
|
: base(generationOffset)
|
|
{
|
|
}
|
|
}
|
|
|
|
protected class ParentComponentAttribute : ComponentDependencyAttribute
|
|
{
|
|
public bool SkipItself { get; set; }
|
|
|
|
public ParentComponentAttribute(int generationOffset = 0)
|
|
: base(generationOffset)
|
|
{
|
|
}
|
|
}
|
|
|
|
protected class SiblingComponentAttribute : ComponentDependencyAttribute
|
|
{
|
|
public bool SkipItself { get; set; }
|
|
|
|
public SiblingComponentAttribute(int generationOffset = 0)
|
|
: base(generationOffset)
|
|
{
|
|
}
|
|
}
|
|
|
|
protected class FamilyComponentAttribute : ComponentDependencyAttribute
|
|
{
|
|
public bool SkipItself { get; set; }
|
|
|
|
public bool FromRoot { get; set; }
|
|
|
|
public int Generations { get; set; }
|
|
|
|
public FamilyComponentAttribute(int generationsBackwards = 1)
|
|
{
|
|
Generations = generationsBackwards;
|
|
}
|
|
|
|
public FamilyComponentAttribute(bool fromRoot, int generationOffset = 0)
|
|
{
|
|
Generations = generationOffset;
|
|
FromRoot = fromRoot;
|
|
}
|
|
}
|
|
|
|
protected class ReferencePointAttribute : PropertyAttribute
|
|
{
|
|
}
|
|
|
|
protected class GameObjectDependencyAttribute : DependencyAttribute
|
|
{
|
|
protected virtual string Named { get; set; }
|
|
|
|
public string GetName()
|
|
{
|
|
return Named;
|
|
}
|
|
|
|
public GameObjectDependencyAttribute(int generationOffset = 0)
|
|
: base(generationOffset)
|
|
{
|
|
}
|
|
}
|
|
|
|
protected class ChildAttribute : GameObjectDependencyAttribute
|
|
{
|
|
public int Index { get; set; }
|
|
|
|
public ChildAttribute(int childIndex = 0)
|
|
{
|
|
Index = childIndex;
|
|
}
|
|
|
|
public ChildAttribute(string name)
|
|
{
|
|
Named = name;
|
|
Index = -1;
|
|
}
|
|
}
|
|
|
|
protected class ParentAttribute : GameObjectDependencyAttribute
|
|
{
|
|
public ParentAttribute(int parentIndex = 0)
|
|
: base(parentIndex)
|
|
{
|
|
}
|
|
|
|
public ParentAttribute(string name)
|
|
{
|
|
Named = name;
|
|
}
|
|
}
|
|
|
|
protected class ReferenceAttribute : GameObjectDependencyAttribute
|
|
{
|
|
protected override string Named
|
|
{
|
|
get
|
|
{
|
|
return base.Of;
|
|
}
|
|
set
|
|
{
|
|
base.Of = value;
|
|
}
|
|
}
|
|
|
|
public ReferenceAttribute(string name)
|
|
{
|
|
base.Of = name;
|
|
}
|
|
}
|
|
|
|
protected class RootAttribute : GameObjectDependencyAttribute
|
|
{
|
|
public int FromTop { get; set; }
|
|
|
|
public RootAttribute(int toSkipFromTop = 0)
|
|
{
|
|
FromTop = toSkipFromTop;
|
|
}
|
|
|
|
public RootAttribute(string name)
|
|
{
|
|
Named = name;
|
|
}
|
|
}
|
|
|
|
protected class SiblingAttribute : GameObjectDependencyAttribute
|
|
{
|
|
public int Index { get; set; }
|
|
|
|
public SiblingAttribute(int siblingIndex)
|
|
{
|
|
Index = siblingIndex;
|
|
}
|
|
|
|
public SiblingAttribute(string name)
|
|
{
|
|
Named = name;
|
|
Index = -1;
|
|
}
|
|
}
|
|
|
|
private class SceneOrDdols
|
|
{
|
|
private Scene? scene;
|
|
|
|
public SceneOrDdols(GameObject go)
|
|
{
|
|
try
|
|
{
|
|
scene = go.scene;
|
|
}
|
|
catch
|
|
{
|
|
scene = null;
|
|
}
|
|
}
|
|
|
|
public bool IsScene()
|
|
{
|
|
return scene.HasValue;
|
|
}
|
|
|
|
public Scene GetScene()
|
|
{
|
|
return scene.Value;
|
|
}
|
|
|
|
public GameObject[] GetRootGameObjects()
|
|
{
|
|
if (IsScene())
|
|
{
|
|
return GetRoots(GetScene()).ToArray();
|
|
}
|
|
return GetDontDestroyOnLoadObjects().ToArray();
|
|
}
|
|
|
|
public int GetRootCount()
|
|
{
|
|
if (IsScene())
|
|
{
|
|
return GetScene().rootCount;
|
|
}
|
|
return GetDontDestroyOnLoadObjects().Count;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
if (IsScene())
|
|
{
|
|
return scene.Value.name;
|
|
}
|
|
return "DDOLs Scene";
|
|
}
|
|
|
|
public bool Equals(Scene scene2)
|
|
{
|
|
if (scene.HasValue)
|
|
{
|
|
return scene.Value == scene2;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
protected internal class ToSkip : MonoBehaviour
|
|
{
|
|
}
|
|
|
|
public static int Verbosity { get; set; }
|
|
|
|
protected static void Log(string msg, bool quietly)
|
|
{
|
|
Log(msg, quietly ? 1 : 0);
|
|
}
|
|
|
|
protected static void Log(string msg, int minVerbosity = 0)
|
|
{
|
|
if (Verbosity >= minVerbosity)
|
|
{
|
|
Debug.Log(msg);
|
|
}
|
|
}
|
|
|
|
protected static void LogWarning(string msg, bool quietly)
|
|
{
|
|
LogWarning(msg, quietly ? 1 : (-1));
|
|
}
|
|
|
|
protected static void LogWarning(string msg, int minVerbosity = -1)
|
|
{
|
|
if (Verbosity >= 2)
|
|
{
|
|
Debug.Log("Warning: " + msg);
|
|
}
|
|
if (Verbosity >= minVerbosity)
|
|
{
|
|
Debug.LogWarning(msg);
|
|
}
|
|
}
|
|
|
|
public static List<GameObject> GetDontDestroyOnLoadObjects()
|
|
{
|
|
List<GameObject> list = new List<GameObject>();
|
|
for (int i = 0; i < SceneManager.sceneCount; i++)
|
|
{
|
|
list.AddRange(SceneManager.GetSceneAt(i).GetRootGameObjects());
|
|
}
|
|
List<GameObject> list2 = new List<GameObject>();
|
|
Transform[] array = Resources.FindObjectsOfTypeAll<Transform>();
|
|
foreach (Transform transform in array)
|
|
{
|
|
if (transform.parent == null && transform.hideFlags == HideFlags.None && !list.Contains(transform.gameObject))
|
|
{
|
|
list2.Add(transform.gameObject);
|
|
}
|
|
}
|
|
list2.Sort((GameObject x, GameObject y) => string.Compare(x.name, y.name));
|
|
return list2;
|
|
}
|
|
|
|
private Transform GetOffsetTransform(Transform t, int offset)
|
|
{
|
|
if (t == null)
|
|
{
|
|
return null;
|
|
}
|
|
if (offset > 0)
|
|
{
|
|
for (int i = 0; i < offset; i++)
|
|
{
|
|
t = t.parent;
|
|
if (t == null)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int j = offset; j < 0; j++)
|
|
{
|
|
if (t.childCount == 0)
|
|
{
|
|
break;
|
|
}
|
|
t = t.GetChild(0);
|
|
}
|
|
}
|
|
return t;
|
|
}
|
|
|
|
private object GetReferenceComponent(List<GameObject> references, MethodInfo method)
|
|
{
|
|
if (references.Count == 0)
|
|
{
|
|
LogWarning("There are no [ReferencePoint] GameObjects to search in for the [ReferenceComponent] in " + this?.ToString() + ". For automatic search use [Component] instead.");
|
|
return null;
|
|
}
|
|
object obj = null;
|
|
foreach (GameObject reference in references)
|
|
{
|
|
Transform obj2;
|
|
try
|
|
{
|
|
obj2 = reference.transform;
|
|
}
|
|
catch
|
|
{
|
|
continue;
|
|
}
|
|
object[] parameters = new Type[0];
|
|
obj = method.Invoke(obj2, parameters);
|
|
if (obj != null)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
return obj;
|
|
}
|
|
|
|
private Transform FindGameObjectInChildren(Transform parent, string name)
|
|
{
|
|
for (int i = 0; i < parent.childCount; i++)
|
|
{
|
|
Transform child = parent.GetChild(i);
|
|
if (child.gameObject.name.Equals(name))
|
|
{
|
|
return child;
|
|
}
|
|
}
|
|
for (int j = 0; j < parent.childCount; j++)
|
|
{
|
|
Transform child2 = parent.GetChild(j);
|
|
Transform transform = FindGameObjectInChildren(child2, name);
|
|
if (transform != null)
|
|
{
|
|
return transform;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private Transform FindGameObjectIn(Transform parent, string name)
|
|
{
|
|
if (parent.gameObject.name.Equals(name))
|
|
{
|
|
return parent;
|
|
}
|
|
return FindGameObjectInChildren(parent, name);
|
|
}
|
|
|
|
private List<Scene> GetScenes(Transform startPoint)
|
|
{
|
|
List<Scene> list = new List<Scene>();
|
|
SceneOrDdols sceneOrDdols = new SceneOrDdols(startPoint?.gameObject);
|
|
if (sceneOrDdols.IsScene())
|
|
{
|
|
list.Add(sceneOrDdols.GetScene());
|
|
}
|
|
for (int i = 0; i < SceneManager.sceneCount; i++)
|
|
{
|
|
Scene sceneAt = SceneManager.GetSceneAt(i);
|
|
if (!sceneOrDdols.Equals(sceneAt))
|
|
{
|
|
list.Add(sceneAt);
|
|
}
|
|
}
|
|
return list;
|
|
}
|
|
|
|
private static List<GameObject> GetRoots(Scene scene)
|
|
{
|
|
List<GameObject> list = new List<GameObject>(scene.GetRootGameObjects());
|
|
list.Sort((GameObject x, GameObject y) => string.Compare(x.name, y.name));
|
|
return list;
|
|
}
|
|
|
|
private GameObject FindGameObject(string name, List<Scene> delayedScenes)
|
|
{
|
|
Transform parent = base.transform;
|
|
Transform transform = FindGameObjectIn(parent, name);
|
|
if (transform != null)
|
|
{
|
|
return transform.gameObject;
|
|
}
|
|
while (parent.parent != null)
|
|
{
|
|
Transform transform2 = parent;
|
|
parent = parent.parent;
|
|
if (transform2.gameObject.name.Equals(name))
|
|
{
|
|
return transform2.gameObject;
|
|
}
|
|
for (int i = 0; i < parent.childCount; i++)
|
|
{
|
|
Transform child = parent.GetChild(i);
|
|
if (child != transform2 && child.gameObject.name.Equals(name))
|
|
{
|
|
return child.gameObject;
|
|
}
|
|
}
|
|
for (int j = 0; j < parent.childCount; j++)
|
|
{
|
|
Transform child2 = parent.GetChild(j);
|
|
if (child2 != transform2)
|
|
{
|
|
transform = FindGameObjectInChildren(parent, name);
|
|
if (transform != null)
|
|
{
|
|
return child2.gameObject;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (parent.name.Equals(name))
|
|
{
|
|
return parent.gameObject;
|
|
}
|
|
List<Scene> scenes = GetScenes(parent);
|
|
foreach (Scene item in scenes)
|
|
{
|
|
foreach (GameObject root in GetRoots(item))
|
|
{
|
|
if (root.name.Equals(name))
|
|
{
|
|
return root;
|
|
}
|
|
}
|
|
if (!item.isLoaded)
|
|
{
|
|
delayedScenes.Add(item);
|
|
}
|
|
}
|
|
List<GameObject> dontDestroyOnLoadObjects = GetDontDestroyOnLoadObjects();
|
|
foreach (GameObject item2 in dontDestroyOnLoadObjects)
|
|
{
|
|
if (item2.name.Equals(name))
|
|
{
|
|
return item2;
|
|
}
|
|
}
|
|
foreach (Scene item3 in scenes)
|
|
{
|
|
foreach (GameObject root2 in GetRoots(item3))
|
|
{
|
|
if (root2.transform != parent)
|
|
{
|
|
transform = FindGameObjectInChildren(root2.transform, name);
|
|
if (transform != null)
|
|
{
|
|
return transform.gameObject;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
foreach (GameObject item4 in dontDestroyOnLoadObjects)
|
|
{
|
|
transform = FindGameObjectInChildren(item4.transform, name);
|
|
if (transform != null)
|
|
{
|
|
return transform.gameObject;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private GameObject FindGameObject(DependencyAttribute a, FieldInfo f, List<GameObject> references, out bool isDelayed)
|
|
{
|
|
isDelayed = false;
|
|
string of = a.Of;
|
|
GameObject gameObject = null;
|
|
List<Scene> list = new List<Scene>();
|
|
if (references.Count != 0)
|
|
{
|
|
FieldInfo field = GetType().GetField(of, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
|
if (field != null && field.GetCustomAttribute(typeof(ReferencePointAttribute)) != null)
|
|
{
|
|
object value = field.GetValue(this);
|
|
try
|
|
{
|
|
if (value != null)
|
|
{
|
|
if (value is GameObject result)
|
|
{
|
|
return result;
|
|
}
|
|
if (value is Transform { gameObject: var result2 })
|
|
{
|
|
return result2;
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
Debug.LogError("The " + field?.ToString() + " field in " + this?.ToString() + " is most likely unassigned.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
gameObject = FindGameObjectIn(references, of);
|
|
if (gameObject == null)
|
|
{
|
|
gameObject = FindGameObject(a.Of, list);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
gameObject = FindGameObject(a.Of, list);
|
|
}
|
|
if (gameObject == null)
|
|
{
|
|
if (list.Count != 0)
|
|
{
|
|
isDelayed = true;
|
|
StartCoroutine(FindGameObjectInScenes(list, a, f, references));
|
|
}
|
|
else
|
|
{
|
|
if (!a.Optional)
|
|
{
|
|
LogWarning("No GameObject named \"" + a.Of + "\" was found for [" + a?.ToString() + "] " + f?.ToString() + " in " + this?.ToString() + ". Creating one...");
|
|
return new GameObject(a.Of);
|
|
}
|
|
Log("No GameObject named \"" + a.Of + "\" was found for [" + a?.ToString() + "] " + f?.ToString() + " in " + this?.ToString() + " but it's optional.", quietly: true);
|
|
}
|
|
}
|
|
return gameObject;
|
|
}
|
|
|
|
private GameObject FindGameObjectIn(IEnumerable<GameObject> list, string name)
|
|
{
|
|
foreach (GameObject item in list)
|
|
{
|
|
try
|
|
{
|
|
if (item.name.Equals(name))
|
|
{
|
|
return item;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private IEnumerator InitDelayedSingleton(Type singletonType, FieldInfo f)
|
|
{
|
|
for (int i = 0; i < SceneManager.sceneCount; i++)
|
|
{
|
|
Scene scene = SceneManager.GetSceneAt(i);
|
|
while (!scene.isLoaded)
|
|
{
|
|
yield return null;
|
|
}
|
|
}
|
|
object value = singletonType.GetProperty("Instance").GetValue(null);
|
|
if (value != null)
|
|
{
|
|
f.SetValue(this, value);
|
|
Log("The [GlobalComponent] " + f?.ToString() + " field in " + this?.ToString() + " has been initialized with a delay. Don't use it in Start() & Awake()!");
|
|
}
|
|
}
|
|
|
|
private IEnumerator WaitForScenesToLoad(IEnumerable<Scene> scenes)
|
|
{
|
|
foreach (Scene scene in scenes)
|
|
{
|
|
while (!scene.isLoaded)
|
|
{
|
|
yield return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
private GameObject FindGameObjectInScenes(IEnumerable<Scene> scenes, string name, bool deepSearch = true)
|
|
{
|
|
foreach (Scene scene in scenes)
|
|
{
|
|
foreach (GameObject root in GetRoots(scene))
|
|
{
|
|
if (root.transform.name.Equals(name))
|
|
{
|
|
return root;
|
|
}
|
|
}
|
|
}
|
|
if (deepSearch)
|
|
{
|
|
foreach (Scene scene2 in scenes)
|
|
{
|
|
foreach (GameObject root2 in GetRoots(scene2))
|
|
{
|
|
Transform transform = FindGameObjectInChildren(root2.transform, name);
|
|
if (transform != null)
|
|
{
|
|
return transform.gameObject;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private IEnumerator FindGameObjectInScenes(IEnumerable<Scene> scenes, DependencyAttribute a, FieldInfo f, List<GameObject> references = null)
|
|
{
|
|
yield return StartCoroutine(WaitForScenesToLoad(scenes));
|
|
GameObject gameObject = FindGameObjectInScenes(scenes, a.Of);
|
|
if (gameObject == null)
|
|
{
|
|
if (a.Optional)
|
|
{
|
|
Log("No GameObject named \"" + a.Of + "\" was found for [" + a?.ToString() + "] " + f?.ToString() + " in " + this?.ToString() + " but it's optional.", quietly: true);
|
|
yield break;
|
|
}
|
|
LogWarning("No GameObject named \"" + a.Of + "\" was found for [" + a?.ToString() + "] " + f?.ToString() + " in " + this?.ToString() + ". Creating one...");
|
|
gameObject = new GameObject(a.Of);
|
|
}
|
|
Log("The [" + a?.ToString() + "(Of = \"" + a.Of + "\")] " + f?.ToString() + " field in " + this?.ToString() + " is initialized with a delay. Don't use it in Start() & Awake()!");
|
|
Transform offsetTransform = GetOffsetTransform(gameObject.transform, a.Offset);
|
|
if (a is GameObjectDependencyAttribute a2)
|
|
{
|
|
InitObjectField(a2, f, offsetTransform);
|
|
}
|
|
else if (a is ComponentDependencyAttribute a3)
|
|
{
|
|
InitComponentField(a3, GetType(), f, offsetTransform, references);
|
|
}
|
|
}
|
|
|
|
private MethodInfo GetTopMethod(Type type)
|
|
{
|
|
return GetType().GetMethod("GetComponent", new Type[0]).MakeGenericMethod(type);
|
|
}
|
|
|
|
private MethodInfo GetDeepMethod(Type type)
|
|
{
|
|
return GetType().GetMethod("GetComponentInChildren", new Type[0]).MakeGenericMethod(type);
|
|
}
|
|
|
|
private bool HasToSkip(Transform t)
|
|
{
|
|
if (t.GetComponent<ToSkip>() == null)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private object FindComponentInChildren(Transform parent, MethodInfo method)
|
|
{
|
|
for (int i = 0; i < parent.childCount; i++)
|
|
{
|
|
Transform child = parent.GetChild(i);
|
|
if (!HasToSkip(child))
|
|
{
|
|
object[] parameters = new Type[0];
|
|
object obj = method.Invoke(child, parameters);
|
|
if (obj != null)
|
|
{
|
|
return obj;
|
|
}
|
|
}
|
|
}
|
|
for (int j = 0; j < parent.childCount; j++)
|
|
{
|
|
Transform child2 = parent.GetChild(j);
|
|
if (!HasToSkip(child2))
|
|
{
|
|
object obj2 = FindComponentInChildren(child2, method);
|
|
if (obj2 != null)
|
|
{
|
|
return obj2;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private object FindComponentIn(Transform parent, MethodInfo method)
|
|
{
|
|
if (HasToSkip(parent))
|
|
{
|
|
return null;
|
|
}
|
|
object[] parameters = new Type[0];
|
|
object obj = method.Invoke(parent, parameters);
|
|
if (obj != null)
|
|
{
|
|
return obj;
|
|
}
|
|
return FindComponentInChildren(parent, method);
|
|
}
|
|
|
|
private IEnumerator FindComponentInScenes(IEnumerable<Scene> scenes, FieldInfo f, bool deepSearch, bool isOptional, GameObject toSkip = null)
|
|
{
|
|
MethodInfo method = (deepSearch ? GetDeepMethod(f.FieldType) : GetTopMethod(f.FieldType));
|
|
if (toSkip != null)
|
|
{
|
|
toSkip.AddComponent<ToSkip>();
|
|
}
|
|
object target = null;
|
|
foreach (Scene scene in scenes)
|
|
{
|
|
while (!scene.isLoaded)
|
|
{
|
|
yield return null;
|
|
}
|
|
foreach (GameObject root in GetRoots(scene))
|
|
{
|
|
if (toSkip == root)
|
|
{
|
|
continue;
|
|
}
|
|
if (!deepSearch || toSkip == null)
|
|
{
|
|
Transform obj = root.transform;
|
|
object[] parameters = new Type[0];
|
|
target = method.Invoke(obj, parameters);
|
|
}
|
|
else
|
|
{
|
|
target = FindComponentIn(root.transform, GetTopMethod(f.FieldType));
|
|
}
|
|
if (target == null)
|
|
{
|
|
continue;
|
|
}
|
|
goto end_IL_008d;
|
|
}
|
|
}
|
|
end_IL_008d:
|
|
if (toSkip != null)
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(toSkip.GetComponent<ToSkip>());
|
|
}
|
|
if (target == null && toSkip != null && deepSearch)
|
|
{
|
|
target = GetComponentOnlyInChildren(toSkip.transform, method);
|
|
}
|
|
if (f.GetValue(this) != null && deepSearch)
|
|
{
|
|
yield break;
|
|
}
|
|
if (target != null)
|
|
{
|
|
f.SetValue(this, target);
|
|
Log("The " + f?.ToString() + " field in " + this?.ToString() + " has been initialized with a delay. Don't use it in Start() & Awake()!");
|
|
}
|
|
else if (f.GetValue(this) == null)
|
|
{
|
|
if (isOptional)
|
|
{
|
|
Log("Instance of " + f?.ToString() + " not found for " + this?.ToString() + " but it's optional.", quietly: true);
|
|
}
|
|
else
|
|
{
|
|
LogWarning("Instance of " + f?.ToString() + " not found for " + this?.ToString() + ". Creating it with a delay... Don't use it in Start() & Awake()!");
|
|
CreateComponent(new GlobalComponentAttribute(), f, null, null);
|
|
}
|
|
}
|
|
}
|
|
|
|
private object FindInRoots(FieldInfo f, bool deepSearch, bool isOptional, GameObject startPoint, out bool isDelayed, bool skip = false)
|
|
{
|
|
MethodInfo methodInfo = (deepSearch ? GetDeepMethod(f.FieldType) : GetTopMethod(f.FieldType));
|
|
Transform parent = null;
|
|
int siblingIndex = -1;
|
|
if (skip && startPoint != null)
|
|
{
|
|
parent = startPoint.transform.parent;
|
|
siblingIndex = startPoint.transform.GetSiblingIndex();
|
|
startPoint.transform.SetParent(null);
|
|
}
|
|
isDelayed = false;
|
|
List<Scene> list = new List<Scene>();
|
|
object obj = null;
|
|
foreach (Scene scene in GetScenes(startPoint?.transform))
|
|
{
|
|
foreach (GameObject root in GetRoots(scene))
|
|
{
|
|
if (!skip || !(startPoint == root))
|
|
{
|
|
Transform obj2 = root.transform;
|
|
object[] parameters = new Type[0];
|
|
obj = methodInfo.Invoke(obj2, parameters);
|
|
if (obj != null)
|
|
{
|
|
goto end_IL_00fb;
|
|
}
|
|
}
|
|
}
|
|
if (!scene.isLoaded)
|
|
{
|
|
list.Add(scene);
|
|
}
|
|
continue;
|
|
end_IL_00fb:
|
|
break;
|
|
}
|
|
if (obj == null)
|
|
{
|
|
foreach (GameObject dontDestroyOnLoadObject in GetDontDestroyOnLoadObjects())
|
|
{
|
|
if (!skip || !(startPoint == dontDestroyOnLoadObject))
|
|
{
|
|
Transform obj3 = dontDestroyOnLoadObject.transform;
|
|
object[] parameters = new Type[0];
|
|
obj = methodInfo.Invoke(obj3, parameters);
|
|
if (obj != null)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (skip && startPoint != null)
|
|
{
|
|
startPoint.transform.SetParent(parent);
|
|
startPoint.transform.SetSiblingIndex(siblingIndex);
|
|
}
|
|
if (obj == null)
|
|
{
|
|
if (list.Count != 0)
|
|
{
|
|
isDelayed = true;
|
|
StartCoroutine(FindComponentInScenes(list, f, deepSearch, isOptional, skip ? startPoint : null));
|
|
}
|
|
else if (skip && startPoint != null && deepSearch)
|
|
{
|
|
obj = GetComponentOnlyInChildren(startPoint.transform, methodInfo);
|
|
}
|
|
}
|
|
return obj;
|
|
}
|
|
|
|
private object GetComponentOnlyInChildren(Transform parent, MethodInfo method)
|
|
{
|
|
for (int i = 0; i < parent.childCount; i++)
|
|
{
|
|
Transform child = parent.GetChild(i);
|
|
object[] parameters = new Type[0];
|
|
object obj = method.Invoke(child, parameters);
|
|
if (obj != null)
|
|
{
|
|
return obj;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private object GetSingletonComponent(FieldInfo f, out bool isDelayed)
|
|
{
|
|
isDelayed = false;
|
|
try
|
|
{
|
|
Type fieldType = f.FieldType;
|
|
Type type = typeof(MonoBehaviourSingleton<>).MakeGenericType(fieldType);
|
|
if (fieldType.IsSubclassOf(type))
|
|
{
|
|
object value = type.GetProperty("Instance").GetValue(null);
|
|
if (value == null)
|
|
{
|
|
StartCoroutine(InitDelayedSingleton(type, f));
|
|
isDelayed = true;
|
|
}
|
|
return value;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private void InitComponentField(ComponentDependencyAttribute a, Type t, FieldInfo f, Transform startPoint, List<GameObject> references)
|
|
{
|
|
object obj = null;
|
|
if (a is ChildComponentAttribute childComponentAttribute)
|
|
{
|
|
if (startPoint != null)
|
|
{
|
|
MethodInfo deepMethod = GetDeepMethod(f.FieldType);
|
|
if (childComponentAttribute.SkipItself)
|
|
{
|
|
obj = GetComponentOnlyInChildren(startPoint, deepMethod);
|
|
}
|
|
else
|
|
{
|
|
Transform obj2 = startPoint;
|
|
object[] parameters = new Type[0];
|
|
obj = deepMethod.Invoke(obj2, parameters);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
obj = FindInRoots(f, deepSearch: true, a.Optional, base.transform.gameObject, out var isDelayed);
|
|
if (isDelayed)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
else if (a is FamilyComponentAttribute familyComponentAttribute)
|
|
{
|
|
Transform transform = startPoint;
|
|
startPoint = ((!familyComponentAttribute.FromRoot) ? GetOffsetTransform(startPoint, familyComponentAttribute.Generations) : GetRoot(startPoint, familyComponentAttribute.Generations));
|
|
if (startPoint != null)
|
|
{
|
|
MethodInfo deepMethod2 = GetDeepMethod(f.FieldType);
|
|
if (familyComponentAttribute.SkipItself)
|
|
{
|
|
Transform parent = transform.parent;
|
|
int siblingIndex = transform.GetSiblingIndex();
|
|
transform.SetParent(null);
|
|
if (startPoint != transform)
|
|
{
|
|
Transform obj3 = startPoint;
|
|
object[] parameters = new Type[0];
|
|
obj = deepMethod2.Invoke(obj3, parameters);
|
|
}
|
|
if (obj == null && startPoint.root != transform)
|
|
{
|
|
obj = GetComponentOnlyInChildren(transform, deepMethod2);
|
|
}
|
|
transform.SetParent(parent);
|
|
transform.SetSiblingIndex(siblingIndex);
|
|
}
|
|
else
|
|
{
|
|
Transform obj4 = startPoint;
|
|
object[] parameters = new Type[0];
|
|
obj = deepMethod2.Invoke(obj4, parameters);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
obj = FindInRoots(f, deepSearch: true, a.Optional, transform?.gameObject, out var isDelayed2, familyComponentAttribute.SkipItself);
|
|
if (isDelayed2)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
else if (a is ParentComponentAttribute parentComponentAttribute)
|
|
{
|
|
if (parentComponentAttribute.SkipItself)
|
|
{
|
|
startPoint = startPoint?.parent;
|
|
}
|
|
if (startPoint != null)
|
|
{
|
|
MethodInfo methodInfo = t.GetMethod("GetComponentInParent", new Type[0]).MakeGenericMethod(f.FieldType);
|
|
Transform obj5 = startPoint;
|
|
object[] parameters = new Type[0];
|
|
obj = methodInfo.Invoke(obj5, parameters);
|
|
}
|
|
}
|
|
else if (a is GlobalComponentAttribute)
|
|
{
|
|
if (a.Of != null && startPoint != null)
|
|
{
|
|
MethodInfo topMethod = GetTopMethod(f.FieldType);
|
|
Transform obj6 = startPoint;
|
|
object[] parameters = new Type[0];
|
|
obj = topMethod.Invoke(obj6, parameters);
|
|
}
|
|
if (obj == null)
|
|
{
|
|
if (!a.Optional)
|
|
{
|
|
obj = GetSingletonComponent(f, out var isDelayed3);
|
|
if (isDelayed3)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
if (obj == null)
|
|
{
|
|
obj = FindInRoots(f, deepSearch: false, a.Optional, startPoint.gameObject, out var isDelayed4);
|
|
if (obj == null)
|
|
{
|
|
obj = FindInRoots(f, deepSearch: true, a.Optional, startPoint.gameObject, out var isDelayed5);
|
|
if (obj == null && (isDelayed4 || isDelayed5))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (a is SiblingComponentAttribute siblingComponentAttribute)
|
|
{
|
|
Transform transform2 = startPoint?.parent;
|
|
if (transform2 != null)
|
|
{
|
|
MethodInfo topMethod2 = GetTopMethod(f.FieldType);
|
|
if (siblingComponentAttribute.SkipItself)
|
|
{
|
|
int siblingIndex2 = startPoint.GetSiblingIndex();
|
|
startPoint.SetParent(null);
|
|
obj = GetComponentOnlyInChildren(transform2, topMethod2);
|
|
startPoint.SetParent(transform2);
|
|
startPoint.SetSiblingIndex(siblingIndex2);
|
|
}
|
|
else
|
|
{
|
|
obj = GetComponentOnlyInChildren(transform2, topMethod2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
obj = FindInRoots(f, deepSearch: false, a.Optional, startPoint?.gameObject, out var isDelayed6, siblingComponentAttribute.SkipItself);
|
|
if (isDelayed6)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
else if (a is OwnComponentAttribute)
|
|
{
|
|
if (startPoint != null)
|
|
{
|
|
MethodInfo topMethod3 = GetTopMethod(f.FieldType);
|
|
Transform obj7 = startPoint;
|
|
object[] parameters = new Type[0];
|
|
obj = topMethod3.Invoke(obj7, parameters);
|
|
}
|
|
}
|
|
else if (a is ReferenceComponentAttribute referenceComponentAttribute)
|
|
{
|
|
MethodInfo methodInfo2 = (referenceComponentAttribute.DeepSearch ? GetDeepMethod(f.FieldType) : GetTopMethod(f.FieldType));
|
|
if (a.Of != null)
|
|
{
|
|
if (startPoint != null)
|
|
{
|
|
Transform obj8 = startPoint;
|
|
object[] parameters = new Type[0];
|
|
obj = methodInfo2.Invoke(obj8, parameters);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
obj = GetReferenceComponent(references, methodInfo2);
|
|
}
|
|
}
|
|
else if (a is ComponentAttribute)
|
|
{
|
|
if (!a.Optional && a.Of == null)
|
|
{
|
|
obj = GetSingletonComponent(f, out var isDelayed7);
|
|
if (isDelayed7)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
MethodInfo topMethod4 = GetTopMethod(f.FieldType);
|
|
if (obj == null && a.Of == null && references.Count != 0)
|
|
{
|
|
obj = GetReferenceComponent(references, topMethod4);
|
|
}
|
|
if (obj == null && startPoint != null)
|
|
{
|
|
MethodInfo deepMethod3 = GetDeepMethod(f.FieldType);
|
|
Transform obj9 = startPoint;
|
|
object[] parameters = new Type[0];
|
|
obj = deepMethod3.Invoke(obj9, parameters);
|
|
while (obj == null)
|
|
{
|
|
Transform transform3 = startPoint;
|
|
Transform parent2 = startPoint.parent;
|
|
if (parent2 == null)
|
|
{
|
|
break;
|
|
}
|
|
startPoint = parent2;
|
|
parameters = new Type[0];
|
|
obj = topMethod4.Invoke(transform3, parameters);
|
|
if (obj == null)
|
|
{
|
|
obj = GetComponentOnlyInChildren(startPoint, topMethod4);
|
|
}
|
|
if (obj != null)
|
|
{
|
|
continue;
|
|
}
|
|
for (int i = 0; i < startPoint.childCount; i++)
|
|
{
|
|
Transform child = startPoint.GetChild(i);
|
|
if (child != transform3)
|
|
{
|
|
obj = GetComponentOnlyInChildren(child, deepMethod3);
|
|
}
|
|
if (obj != null)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (obj == null)
|
|
{
|
|
if (startPoint != null)
|
|
{
|
|
Transform obj10 = startPoint;
|
|
object[] parameters = new Type[0];
|
|
obj = topMethod4.Invoke(obj10, parameters);
|
|
}
|
|
if (obj == null)
|
|
{
|
|
obj = FindInRoots(f, deepSearch: true, a.Optional, startPoint?.gameObject, out var isDelayed8, startPoint != null);
|
|
if (isDelayed8)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (obj == null)
|
|
{
|
|
if (a.Optional)
|
|
{
|
|
Log("Instance of [" + a?.ToString() + "] " + f?.ToString() + " not found for " + this?.ToString() + " but it's optional.", quietly: true);
|
|
}
|
|
else
|
|
{
|
|
LogWarning("Instance of [" + a?.ToString() + "] " + f?.ToString() + " not found for " + this?.ToString() + ". Creating one...");
|
|
CreateComponent(a, f, startPoint, references);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
f.SetValue(this, obj);
|
|
}
|
|
}
|
|
|
|
private Transform GetChild(Transform parent, int index)
|
|
{
|
|
if (index < 0 || index >= parent.childCount)
|
|
{
|
|
return null;
|
|
}
|
|
return parent.GetChild(index);
|
|
}
|
|
|
|
private Transform GetRoot(Transform startPoint, int offsetFromTop)
|
|
{
|
|
int num = 0;
|
|
Transform transform = startPoint;
|
|
while (transform.parent != null)
|
|
{
|
|
num++;
|
|
transform = transform.parent;
|
|
}
|
|
if (offsetFromTop != 0)
|
|
{
|
|
transform = startPoint;
|
|
num -= Mathf.Abs(offsetFromTop);
|
|
transform = GetOffsetTransform(transform, num);
|
|
}
|
|
return transform;
|
|
}
|
|
|
|
private Transform GetTransformByStartPoint(GameObjectDependencyAttribute a, FieldInfo f, Transform startPoint)
|
|
{
|
|
if (startPoint == null)
|
|
{
|
|
return null;
|
|
}
|
|
Transform transform = null;
|
|
if (a is ParentAttribute)
|
|
{
|
|
transform = startPoint.parent;
|
|
}
|
|
else if (a is ChildAttribute childAttribute)
|
|
{
|
|
transform = GetChild(startPoint, childAttribute.Index);
|
|
if (transform == null)
|
|
{
|
|
string msg = "ChildIndex of [" + a?.ToString() + "(" + childAttribute.Index + ")] " + f?.ToString() + " in " + this?.ToString() + " is out of rage of " + startPoint.name + "'s children.";
|
|
if (a.Optional)
|
|
{
|
|
Log(msg, quietly: true);
|
|
}
|
|
else
|
|
{
|
|
LogWarning(msg);
|
|
}
|
|
}
|
|
}
|
|
else if (a is SiblingAttribute siblingAttribute)
|
|
{
|
|
Transform parent = startPoint.parent;
|
|
if (parent != null)
|
|
{
|
|
transform = GetChild(parent, siblingAttribute.Index);
|
|
if (transform == null)
|
|
{
|
|
string msg2 = "ChildIndex of [" + a?.ToString() + "(" + siblingAttribute.Index + ")] " + f?.ToString() + " in " + this?.ToString() + " is out of rage of " + parent.name + "'s children.";
|
|
if (a.Optional)
|
|
{
|
|
Log(msg2, quietly: true);
|
|
}
|
|
else
|
|
{
|
|
LogWarning(msg2);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SceneOrDdols sceneOrDdols = new SceneOrDdols(startPoint.gameObject);
|
|
GameObject[] rootGameObjects = sceneOrDdols.GetRootGameObjects();
|
|
int index = siblingAttribute.Index;
|
|
if (index < 0 || index >= rootGameObjects.Length)
|
|
{
|
|
string msg3 = "ChildIndex of [" + a?.ToString() + "(" + index + ")] " + f?.ToString() + " in " + this?.ToString() + " is out of rage of " + sceneOrDdols?.ToString() + "'s roots.";
|
|
if (a.Optional)
|
|
{
|
|
Log(msg3, quietly: true);
|
|
}
|
|
else
|
|
{
|
|
LogWarning(msg3);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
transform = rootGameObjects[index].transform;
|
|
}
|
|
}
|
|
}
|
|
else if (a is ReferenceAttribute)
|
|
{
|
|
transform = startPoint;
|
|
}
|
|
else if (a is RootAttribute rootAttribute)
|
|
{
|
|
transform = GetRoot(startPoint, rootAttribute.FromTop);
|
|
}
|
|
return transform;
|
|
}
|
|
|
|
private IEnumerator FindGameObjectInRoots(GameObjectDependencyAttribute a, IEnumerable<Scene> scenes, FieldInfo f, bool isOptional, string name, bool deepSearch)
|
|
{
|
|
yield return StartCoroutine(WaitForScenesToLoad(scenes));
|
|
GameObject gameObject = FindGameObjectInScenes(scenes, name, deepSearch);
|
|
if (gameObject == null)
|
|
{
|
|
if (f.GetValue(this) != null)
|
|
{
|
|
yield break;
|
|
}
|
|
if (isOptional)
|
|
{
|
|
Log("No GameObject named \"" + name + "\" was found for [" + a?.ToString() + "] " + f?.ToString() + " in " + this?.ToString() + " but it's optional.", quietly: true);
|
|
yield break;
|
|
}
|
|
LogWarning("No GameObject named \"" + name + "\" was found for [" + a?.ToString() + "] " + f?.ToString() + " in " + this?.ToString() + ". Creating one...");
|
|
gameObject = new GameObject(name);
|
|
}
|
|
if (f.FieldType == typeof(GameObject))
|
|
{
|
|
f.SetValue(this, gameObject);
|
|
}
|
|
else
|
|
{
|
|
f.SetValue(this, gameObject.transform);
|
|
}
|
|
Log("The [" + a?.ToString() + "(Named = \"" + name + "\")] " + f?.ToString() + " field in " + this?.ToString() + " has been initialized with a delay. Don't use it in Start() & Awake()!");
|
|
}
|
|
|
|
private Transform FindGameObjectInRoots(GameObjectDependencyAttribute a, FieldInfo f, bool isOptional, string name, bool deepSearch, out bool isDelayed)
|
|
{
|
|
isDelayed = false;
|
|
List<Scene> list = new List<Scene>();
|
|
foreach (Scene scene in GetScenes(base.transform))
|
|
{
|
|
foreach (GameObject root in GetRoots(scene))
|
|
{
|
|
if (deepSearch)
|
|
{
|
|
Transform transform = FindGameObjectInChildren(root.transform, name);
|
|
if (transform != null)
|
|
{
|
|
return transform;
|
|
}
|
|
}
|
|
else if (root.transform.name.Equals(name))
|
|
{
|
|
return root.transform;
|
|
}
|
|
}
|
|
if (!scene.isLoaded)
|
|
{
|
|
list.Add(scene);
|
|
}
|
|
}
|
|
if (list.Count != 0)
|
|
{
|
|
isDelayed = true;
|
|
StartCoroutine(FindGameObjectInRoots(a, list, f, isOptional, name, deepSearch));
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private Transform GetTransformByName(GameObjectDependencyAttribute a, FieldInfo f, Transform startPoint, out bool isDelayed)
|
|
{
|
|
isDelayed = false;
|
|
string value = a.GetName();
|
|
if (a is ParentAttribute)
|
|
{
|
|
if (startPoint != null)
|
|
{
|
|
while (startPoint.parent != null)
|
|
{
|
|
startPoint = startPoint.parent;
|
|
if (startPoint.name.Equals(value))
|
|
{
|
|
return startPoint;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
if (a is ChildAttribute)
|
|
{
|
|
if (startPoint != null)
|
|
{
|
|
return FindGameObjectInChildren(startPoint, value);
|
|
}
|
|
return FindGameObjectInRoots(a, f, a.Optional, value, deepSearch: true, out isDelayed);
|
|
}
|
|
if (a is SiblingAttribute)
|
|
{
|
|
startPoint = startPoint?.parent;
|
|
if (startPoint != null)
|
|
{
|
|
for (int i = 0; i < startPoint.childCount; i++)
|
|
{
|
|
Transform child = startPoint.GetChild(i);
|
|
if (child.name.Equals(value))
|
|
{
|
|
return child;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
return FindGameObjectInRoots(a, f, a.Optional, value, deepSearch: false, out isDelayed);
|
|
}
|
|
if (a is ReferenceAttribute)
|
|
{
|
|
return startPoint;
|
|
}
|
|
if (a is RootAttribute rootAttribute)
|
|
{
|
|
if (startPoint != null)
|
|
{
|
|
int num = 0;
|
|
List<Transform> list = new List<Transform>();
|
|
Transform transform = startPoint;
|
|
while (transform.parent != null)
|
|
{
|
|
num++;
|
|
transform = transform.parent;
|
|
}
|
|
transform = startPoint;
|
|
num -= Mathf.Abs(rootAttribute.FromTop);
|
|
if (num < 0)
|
|
{
|
|
transform = GetOffsetTransform(startPoint, num);
|
|
}
|
|
for (int j = 0; j < Mathf.Abs(num); j++)
|
|
{
|
|
list.Add(transform);
|
|
if (transform.parent == null)
|
|
{
|
|
break;
|
|
}
|
|
transform = transform.parent;
|
|
}
|
|
if (num < 0)
|
|
{
|
|
list.Reverse();
|
|
transform = GetOffsetTransform(startPoint, num);
|
|
}
|
|
if (transform.name.Equals(value))
|
|
{
|
|
return transform;
|
|
}
|
|
SiblingAttribute siblingAttribute = new SiblingAttribute(value);
|
|
siblingAttribute.Optional = rootAttribute.Optional;
|
|
Transform transformByName = GetTransformByName(siblingAttribute, f, transform, out isDelayed);
|
|
if (transformByName != null)
|
|
{
|
|
return transformByName;
|
|
}
|
|
for (int num2 = list.Count - 1; num2 >= 0; num2--)
|
|
{
|
|
Transform transform2 = list[num2];
|
|
if (transform2.name.Equals(value))
|
|
{
|
|
return transform2;
|
|
}
|
|
}
|
|
}
|
|
else if (rootAttribute.FromTop == 0)
|
|
{
|
|
return FindGameObjectInRoots(a, f, a.Optional, value, deepSearch: false, out isDelayed);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private void InitObjectField(GameObjectDependencyAttribute a, FieldInfo f, Transform startPoint)
|
|
{
|
|
Transform transform;
|
|
if (a.GetName() == null)
|
|
{
|
|
transform = GetTransformByStartPoint(a, f, startPoint);
|
|
}
|
|
else
|
|
{
|
|
transform = GetTransformByName(a, f, startPoint, out var isDelayed);
|
|
if (isDelayed && !(a is RootAttribute))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
if (transform == null)
|
|
{
|
|
if (a.Optional)
|
|
{
|
|
Log("Instance of [" + a?.ToString() + "] " + f?.ToString() + " not found for " + this?.ToString() + " but it's optional.", quietly: true);
|
|
}
|
|
else
|
|
{
|
|
LogWarning("Instance of [" + a?.ToString() + "] " + f?.ToString() + " not found for " + this?.ToString() + ".");
|
|
CreateGameObject(a, f, startPoint);
|
|
}
|
|
}
|
|
else if (f.FieldType == typeof(GameObject))
|
|
{
|
|
f.SetValue(this, transform.gameObject);
|
|
}
|
|
else
|
|
{
|
|
f.SetValue(this, transform);
|
|
}
|
|
}
|
|
|
|
private void CreateGameObject(GameObjectDependencyAttribute a, FieldInfo f, Transform startPoint)
|
|
{
|
|
if (startPoint == null)
|
|
{
|
|
return;
|
|
}
|
|
string text = a.GetName() ?? f.Name;
|
|
Transform transform = new GameObject(text).transform;
|
|
if (a is ParentAttribute)
|
|
{
|
|
transform.SetParent(startPoint.parent);
|
|
startPoint.SetParent(transform);
|
|
}
|
|
else if (a is ChildAttribute childAttribute)
|
|
{
|
|
for (int i = startPoint.childCount; i < childAttribute.Index; i++)
|
|
{
|
|
new GameObject("Child" + (i + 1)).transform.SetParent(startPoint);
|
|
}
|
|
transform.SetParent(startPoint);
|
|
if (childAttribute.Index >= 0)
|
|
{
|
|
transform.SetSiblingIndex(childAttribute.Index);
|
|
}
|
|
}
|
|
else if (a is SiblingAttribute siblingAttribute)
|
|
{
|
|
Transform parent = startPoint.parent;
|
|
for (int j = parent?.childCount ?? new SceneOrDdols(startPoint.gameObject).GetRootCount(); j < siblingAttribute.Index; j++)
|
|
{
|
|
Transform obj = new GameObject("Sibling" + (j + 1)).transform;
|
|
obj.SetParent(startPoint);
|
|
obj.SetParent(parent);
|
|
}
|
|
transform.SetParent(startPoint);
|
|
transform.SetParent(parent);
|
|
if (siblingAttribute.Index >= 0)
|
|
{
|
|
transform.SetSiblingIndex(siblingAttribute.Index);
|
|
}
|
|
}
|
|
else if (a is RootAttribute rootAttribute)
|
|
{
|
|
if (rootAttribute.FromTop != 0)
|
|
{
|
|
int num = 0;
|
|
Transform transform2 = startPoint;
|
|
while (transform2.parent != null)
|
|
{
|
|
num++;
|
|
transform2 = transform2.parent;
|
|
}
|
|
transform2 = startPoint;
|
|
num -= Mathf.Abs(rootAttribute.FromTop);
|
|
transform2 = GetOffsetTransform(transform2, num);
|
|
transform.SetParent(transform2.parent);
|
|
}
|
|
else
|
|
{
|
|
transform.SetParent(startPoint);
|
|
transform.SetParent(null);
|
|
}
|
|
}
|
|
if (f.FieldType == typeof(GameObject))
|
|
{
|
|
f.SetValue(this, transform.gameObject);
|
|
}
|
|
else
|
|
{
|
|
f.SetValue(this, transform);
|
|
}
|
|
Log("New GameObject called " + text + " has been created.", quietly: true);
|
|
}
|
|
|
|
private void CreateComponent(ComponentDependencyAttribute a, FieldInfo f, Transform startPoint, List<GameObject> references)
|
|
{
|
|
Type fieldType = f.FieldType;
|
|
Component value = null;
|
|
if (a is ChildComponentAttribute || a is FamilyComponentAttribute || a is SiblingComponentAttribute)
|
|
{
|
|
if (a is SiblingComponentAttribute)
|
|
{
|
|
startPoint = startPoint?.parent;
|
|
}
|
|
GameObject obj = new GameObject(fieldType.Name, fieldType);
|
|
value = obj.GetComponent(fieldType);
|
|
obj.transform.SetParent(startPoint);
|
|
}
|
|
else if (a is ParentComponentAttribute || a is GlobalComponentAttribute || a is OwnComponentAttribute || a is ComponentAttribute)
|
|
{
|
|
value = ((!(startPoint != null)) ? new GameObject(fieldType.Name, fieldType).GetComponent(fieldType) : startPoint.gameObject.AddComponent(fieldType));
|
|
}
|
|
else if (a is ReferenceComponentAttribute)
|
|
{
|
|
if (a.Of != null || references.Count == 0)
|
|
{
|
|
if (startPoint != null)
|
|
{
|
|
value = startPoint.gameObject.AddComponent(fieldType);
|
|
}
|
|
else
|
|
{
|
|
GameObject obj2 = new GameObject(fieldType.Name, fieldType);
|
|
value = obj2.GetComponent(fieldType);
|
|
obj2.transform.SetParent(base.transform);
|
|
obj2.transform.SetParent(null);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
value = references[Mathf.Min(a.Offset, references.Count - 1)].AddComponent(fieldType);
|
|
}
|
|
}
|
|
f.SetValue(this, value);
|
|
Log("New component [" + a?.ToString() + "] " + f?.ToString() + " for " + this?.ToString() + " has been created.", quietly: true);
|
|
}
|
|
|
|
protected void Awake()
|
|
{
|
|
Type type = GetType();
|
|
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
|
List<GameObject> list = new List<GameObject>();
|
|
FieldInfo[] array = fields;
|
|
foreach (FieldInfo fieldInfo in array)
|
|
{
|
|
object[] customAttributes = fieldInfo.GetCustomAttributes(typeof(GameObjectDependencyAttribute), inherit: true);
|
|
if (customAttributes.Length > 1)
|
|
{
|
|
for (int j = 0; j < customAttributes.Length - 1; j++)
|
|
{
|
|
((GameObjectDependencyAttribute)customAttributes[j]).Optional = true;
|
|
}
|
|
}
|
|
object[] array2 = customAttributes;
|
|
for (int k = 0; k < array2.Length; k++)
|
|
{
|
|
GameObjectDependencyAttribute gameObjectDependencyAttribute = (GameObjectDependencyAttribute)array2[k];
|
|
if (fieldInfo.IsPublic && !fieldInfo.IsNotSerialized)
|
|
{
|
|
LogWarning("You tried to inject a public (serialized) GameObject! (" + fieldInfo?.ToString() + " in " + this?.ToString() + ") It should be private or marked with [NonSerialized], otherwise it may conflict with the Unity serializer and the dependency may not be injected.");
|
|
}
|
|
if (fieldInfo.GetValue(this) != null)
|
|
{
|
|
break;
|
|
}
|
|
if (fieldInfo.FieldType != typeof(GameObject) && fieldInfo.FieldType != typeof(Transform))
|
|
{
|
|
Debug.LogError(gameObjectDependencyAttribute?.ToString() + " cannot be applied to " + fieldInfo?.ToString() + " in " + this?.ToString() + " as it's not of GameObject/Transform type.");
|
|
}
|
|
Transform transform = null;
|
|
if (gameObjectDependencyAttribute.Of != null)
|
|
{
|
|
transform = FindGameObject(gameObjectDependencyAttribute, fieldInfo, list, out var _)?.transform;
|
|
if (transform == null)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
transform = base.transform;
|
|
}
|
|
transform = GetOffsetTransform(transform, gameObjectDependencyAttribute.Offset);
|
|
InitObjectField(gameObjectDependencyAttribute, fieldInfo, transform);
|
|
}
|
|
if (fieldInfo.GetCustomAttribute(typeof(ReferencePointAttribute)) != null)
|
|
{
|
|
if (fieldInfo.FieldType == typeof(GameObject))
|
|
{
|
|
list.Add((GameObject)fieldInfo.GetValue(this));
|
|
continue;
|
|
}
|
|
if (fieldInfo.FieldType == typeof(Transform))
|
|
{
|
|
list.Add(((Transform)fieldInfo.GetValue(this)).gameObject);
|
|
continue;
|
|
}
|
|
Debug.LogError("ReferencePointAttribute cannot be applied to " + fieldInfo?.ToString() + " in " + this?.ToString() + " as it's not of GameObject/Transform type.");
|
|
}
|
|
}
|
|
array = fields;
|
|
foreach (FieldInfo fieldInfo2 in array)
|
|
{
|
|
object[] customAttributes2 = fieldInfo2.GetCustomAttributes(typeof(ComponentDependencyAttribute), inherit: true);
|
|
if (customAttributes2.Length > 1)
|
|
{
|
|
for (int l = 0; l < customAttributes2.Length - 1; l++)
|
|
{
|
|
((ComponentDependencyAttribute)customAttributes2[l]).Optional = true;
|
|
}
|
|
}
|
|
object[] array2 = customAttributes2;
|
|
for (int k = 0; k < array2.Length; k++)
|
|
{
|
|
ComponentDependencyAttribute componentDependencyAttribute = (ComponentDependencyAttribute)array2[k];
|
|
if (fieldInfo2.GetValue(this) != null)
|
|
{
|
|
break;
|
|
}
|
|
Transform transform2 = null;
|
|
if (componentDependencyAttribute.Of != null)
|
|
{
|
|
transform2 = FindGameObject(componentDependencyAttribute, fieldInfo2, list, out var _)?.transform;
|
|
if (transform2 == null)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
transform2 = base.transform;
|
|
}
|
|
transform2 = GetOffsetTransform(transform2, componentDependencyAttribute.Offset);
|
|
InitComponentField(componentDependencyAttribute, type, fieldInfo2, transform2, list);
|
|
}
|
|
}
|
|
}
|
|
}
|