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;
}
}
}