using System; using UnityEngine; using System.Linq; using System.Reflection; using ILRuntime.Reflection; using ILRuntime.CLR.TypeSystem; using System.Collections.Generic; using Object = UnityEngine.Object; using UnityEngine.SceneManagement; using ILRuntime.Runtime.Enviorment; using ILRuntime.Runtime.Intepreter; using Component = UnityEngine.Component; #if PLUGIN_NINO using Nino.Shared.IO; #endif namespace JEngine.Core { public static partial class Tools { /// /// 获取对象的gameObject /// /// /// public static GameObject GetGameObject(this object ins) { GameObject instance; if (ins is GameObject g) { instance = g; } else if (ins is ILTypeInstance ilt) { instance = FindGOForHotClass(ilt); } else if(ins is Transform t) { instance = t.gameObject; } else if (ins is Component c) { instance = c.gameObject; } else { instance = null; } return instance; } /// /// 找到热更对象的gameObject /// /// /// public static GameObject FindGOForHotClass(this ILTypeInstance instance) { var returnType = instance.Type; PropertyInfo pi = null; if (returnType.ReflectionType == typeof(MonoBehaviour)) { pi = returnType.ReflectionType.GetProperty("gameObject"); } if (returnType.ReflectionType.IsSubclassOf(typeof(MonoBehaviour))) { if (returnType.ReflectionType.BaseType != null) { pi = returnType.ReflectionType.BaseType.GetProperty("gameObject"); } } return pi?.GetValue(instance.CLRInstance) as GameObject; } /// /// 获取全部Type对象(包含隐藏的) /// /// /// public static List FindObjectsOfTypeAll() where T: Object { if (!Application.isPlaying) { return SceneManager.GetActiveScene().GetRootGameObjects() .SelectMany(g => g.GetComponentsInChildren(true)) .ToList(); } #if PLUGIN_NINO List all = null; List temp = null; foreach (var scene in ClassBindMgr.LoadedScenes) { if (all == null) { all = ObjectPool>.Peak() != null ? ObjectPool>.Request() : new List(scene.rootCount); all.Clear(); } if (temp == null) { temp = ObjectPool>.Peak() != null ? ObjectPool>.Request() : new List(scene.rootCount); } scene.GetRootGameObjects(temp); all.AddRange(temp); } if (all == null) { return new List(); } temp.Clear(); ObjectPool>.Return(temp); List lst = ObjectPool>.Peak() != null ? ObjectPool>.Request() : new List(all.Count); List tempT = ObjectPool>.Peak() != null ? ObjectPool>.Request() : new List(all.Count); lst.Clear(); tempT.Clear(); foreach (var gameObject in all) { gameObject.GetComponentsInChildren(true, tempT); lst.AddRange(tempT); tempT.Clear(); } all.Clear(); ObjectPool>.Return(all); ObjectPool>.Return(tempT); return lst; #endif return ClassBindMgr.LoadedScenes.SelectMany(scene => scene.GetRootGameObjects()) .SelectMany(g => g.GetComponentsInChildren(true)) .ToList(); return UnityEngine.Object.FindObjectsOfType().ToList(); } /// /// Get a class instance from a gameObject, can be either hot or local /// /// /// /// public static object GetInstanceFromGO(this Type fieldType, Object obj) { if (obj.GetType() == fieldType || obj.GetType().FullName == fieldType.FullName) { return obj; } GameObject go; if (obj is GameObject o) { go = o; } else { go = (obj as Component)?.gameObject; } if (go is null) return null; if (fieldType == typeof(Transform)) { var rect = go.GetComponent(); if (rect != null) { return rect; } return go.transform; } if (fieldType is ILRuntimeType ilType) //如果在热更中 { var components = go.GetComponents(); foreach (var c in components) { if (c.ILInstance.Type.CanAssignTo(ilType.ILType)) { return c.ILInstance; } } } else { if (fieldType is ILRuntimeWrapperType type) { fieldType = type.RealType; } return go.GetComponent(fieldType); } return null; } /// /// 获取场景内全部MonoBehaviour适配器(CrossBindingAdaptorType) /// /// public static List GetAllMonoAdapters() { List adapters = new List(); List searchResult = new List(); foreach (var scene in ClassBindMgr.LoadedScenes) { var rootGameObjects = scene.GetRootGameObjects(); foreach (var rootGameObject in rootGameObjects) { searchResult.Clear(); rootGameObject.GetComponentsInChildren(true, searchResult); foreach (var crossBindingAdaptorType in searchResult) { if (crossBindingAdaptorType?.ILInstance != null) { adapters.Add(crossBindingAdaptorType); } } } } return adapters; } /// /// 获取热更对象 /// /// /// /// public static object GetHotComponent(this GameObject gameObject, string typeName) { var clrInstances = gameObject.GetComponents(); var type = InitJEngine.Appdomain.GetType(typeName); foreach (var clrInstance in clrInstances) { if (clrInstance.ILInstance != null && clrInstance.ILInstance.Type.CanAssignTo(type)) { return clrInstance.ILInstance; } } return null; } /// /// 获取热更对象 /// /// /// /// public static object[] GetHotComponents(this GameObject gameObject, string typeName) { var clrInstances = gameObject.GetComponents(); var type = InitJEngine.Appdomain.GetType(typeName); object[] ret = new object[clrInstances.Length]; int i = 0; foreach (var clrInstance in clrInstances) { if (clrInstance.ILInstance != null && clrInstance.ILInstance.Type.CanAssignTo(type)) { ret[i] = clrInstance.ILInstance; i++; } } Array.Resize(ref ret, i); return ret; } /// /// 获取热更对象 /// /// /// /// public static object GetHotComponent(this GameObject gameObject, ILType type) { var clrInstances = gameObject.GetComponents(); foreach (var clrInstance in clrInstances) { if (clrInstance.ILInstance != null && clrInstance.ILInstance.Type.CanAssignTo(type)) { return clrInstance.ILInstance; } } return null; } /// /// 获取热更对象 /// /// /// /// public static object[] GetHotComponents(this GameObject gameObject, ILType type) { var clrInstances = gameObject.GetComponents(); object[] ret = new object[clrInstances.Length]; int i = 0; foreach (var clrInstance in clrInstances) { if (clrInstance.ILInstance != null && clrInstance.ILInstance.Type.CanAssignTo(type)) { ret[i] = clrInstance.ILInstance; i++; } } Array.Resize(ref ret, i); return ret; } /// /// 获取热更对象 /// /// /// /// public static object GetHotComponent(this CrossBindingAdaptorType[] adapters, ILType type) { foreach (var adapter in adapters) { if (adapter.ILInstance != null && adapter.ILInstance.Type.CanAssignTo(type)) { return adapter.ILInstance; } } return null; } /// /// 获取热更对象 /// /// /// /// public static object[] GetHotComponents(this CrossBindingAdaptorType[] adapters, ILType type) { object[] ret = new object[adapters.Length]; int i = 0; foreach (var adapter in adapters) { if (adapter.ILInstance != null && adapter.ILInstance.Type.CanAssignTo(type)) { ret[i] = adapter.ILInstance; i++; } } Array.Resize(ref ret, i); return ret; } /// /// 获取热更对象 /// /// /// /// public static object GetHotComponent(this List adapters, ILType type) { foreach (var adapter in adapters) { if (adapter.ILInstance != null && adapter.ILInstance.Type.CanAssignTo(type)) { return adapter.ILInstance; } } return null; } /// /// 获取热更对象 /// /// /// /// public static object[] GetHotComponents(this List adapters, ILType type) { object[] ret = new object[adapters.Count]; int i = 0; foreach (var adapter in adapters) { if (adapter.ILInstance != null && adapter.ILInstance.Type.CanAssignTo(type)) { ret[i] = adapter.ILInstance; i++; } } Array.Resize(ref ret, i); return ret; } /// /// 删除挂载GameObject上的热更脚本 /// /// /// public static void DestroyHotComponent(this GameObject gameObject, object hotObject) { var clrInstances = gameObject.GetComponents(); foreach (var clrInstance in clrInstances) { if (clrInstance.ILInstance != null && Equals(clrInstance.ILInstance, hotObject)) { Object.Destroy(clrInstance as MonoBehaviour); } } } /// /// 获取子对象上的热更对象 /// /// /// /// public static object[] GetHotComponentInChildren(this GameObject gameObject, string typeName) { var clrInstances = gameObject.GetComponentsInChildren(true); var type = InitJEngine.Appdomain.GetType(typeName); object[] ret = new object[clrInstances.Length]; int i = 0; foreach (var clrInstance in clrInstances) { if (clrInstance.ILInstance != null && clrInstance.ILInstance.Type.CanAssignTo(type)) { ret[i] = clrInstance.ILInstance; i++; } } Array.Resize(ref ret, i); return ret; } } }