智能网站建设软件有哪些方面,海口网红图书馆,宁波网络营销平台,微信小程序短链接生成反射实现切换Gameobjecect-Comp之前介绍过Kinematic Character Controller这个插件这个插件很容易和另外一个插件混淆#xff0c;两个作者头像比较相像#xff0c;而且这个插件的作者不太喜欢露脸#xff08;他现在做Dot-CharacterControl去了#xff09;#xff0c;几乎网…反射实现切换Gameobjecect-Comp之前介绍过Kinematic Character Controller这个插件这个插件很容易和另外一个插件混淆两个作者头像比较相像而且这个插件的作者不太喜欢露脸他现在做Dot-CharacterControl去了几乎网上找到的都是另一个CharacterController插件但其实这个控件例子不少的都是走跑和跳等例子。而且例子内代码结构是多个例子场景则多个命名空间 每个命名空间内一个MyController(同名整个Kinematic Character Controller几乎有十几个MyController咋一看怎么不使用继承不太面向对象的感觉太不专业但实际上也和面向对象的使用无差我们的需求来了一个GameObject 包含一个逻辑 Mono是否可以直接右键替换??切换的同时重点是如何把Mono的SerilizeField一些关联go也一并替换这就是用到反射了否则就得一个个场景切换代码比较麻烦所以如下1原来的Kinematic逻辑2.切换成自定义代码整个Component的切换实现就是利用了反射和Unity Editor的特性封装了一下代码可直接调用//调用方法
//原目標即使是接口也可以通过.GetComponent()获取
var currController go.GetComponentICharacterController();//curr Instance
var motorSource ReflectionHelper.GetCompField(go,currController.GetType().ToString(),Motor);
Debug.LogError(motorSource);static class ReflectionHelper
{/// summary/// 因为UnityEditor原因这样获取会获取到Editor库。。。。(如何 ReflectionHelper 类不放在Editor也是不会存在获取到Editor库问题/// /summarypublic static IEnumerable CreateAllInstancesOfT(){return typeof(ReflectionHelper).Assembly.GetTypes() //获取当前类库下所有类型//.Where(t typeof(T).IsAssignableFrom(t)) //获取间接或直接继承t的所有类型//.Where(t !t.IsAbstract t.IsClass) //获取非抽象类 排除接口继承//.Select(t (T) Activator.CreateInstance(t)); //创造实例并返回结果项目需求可删除.Select(tt.FullName);}/// summary/// (直接指向,所以能获取Unity Runtime库/// /summary/// returns/returnspublic static IEnumerable GetAllClassesT(){// var name Selection.activeObject.name;//获取 Scene 中 GameObjectSystem.Reflection.Assembly assembly System.Reflection.Assembly.GetExecutingAssembly();var dict System.IO.Path.GetDirectoryName(assembly.Location);assembly System.Reflection.Assembly.LoadFile(System.IO.Path.Combine(dict, Assembly-CSharp.dll));return assembly.GetTypes().Where(t typeof(T).IsAssignableFrom(t)) //获取间接或直接继承t的所有类型.Where(t !t.IsAbstract t.IsClass) //获取非抽象类 排除接口继承.Select(tt.FullName);}/// summary/// 根据 type 获取go 的 component 的值/// /summary/// param namego/param/// param nametypeStringcurrController.GetType().ToString()/param/// param namename类的字段 名字/param/// returns/returnspublic static object GetCompField(GameObject go, string typeString,string name){var assemblies AppDomain.CurrentDomain.GetAssemblies();var defaultAssembly assemblies.First(assembly assembly.GetName().Name Assembly-CSharp);Type typSource defaultAssembly.GetType(typeString);var currInstance go.GetComponent(typSource);FieldInfo fieldSource typSource.GetField(name);return fieldSource.GetValue(currInstance);}public static bool SetCompField(object obj,object objValue, string typeString, string name){var assemblies AppDomain.CurrentDomain.GetAssemblies();var defaultAssembly assemblies.First(assembly assembly.GetName().Name Assembly-CSharp);Type typSource defaultAssembly.GetType(typeString);if (typSource null) return false;FieldInfo fieldSource typSource.GetField(name);fieldSource.SetValue(obj,objValue);return true;}
}
Project View查找的代码实现void Find(System.Type type)
{//step 1:find ref in assets//filter all GameObject from assetsso-called Prefabvar guids AssetDatabase.FindAssets(t:GameObject);findResult new Liststring();var tp typeof(GameObject);foreach (var guid in guids){var path AssetDatabase.GUIDToAssetPath(guid);//load Prefabvar obj AssetDatabase.LoadAssetAtPath(path, tp) as GameObject;//check whether prefab contains script with type typeif (obj ! null){var cmp obj.GetComponent(type);if (cmp null){cmp obj.GetComponentInChildren(type);}if (cmp ! null){findResult.Add(path);}}}//step 2: find ref in scenes//save current scenestring curScene EditorApplication.currentScene;EditorApplication.SaveScene();//find all scenes from dataPathstring[] scenes Directory.GetFiles(Application.dataPath, *.unity, SearchOption.AllDirectories);//iterates all scenes foreach (var scene in scenes){EditorApplication.OpenScene(scene);//iterates all gameObjectsforeach (GameObject obj in FindObjectsOfTypeGameObject()){var cmp obj.GetComponent(type);if (cmp null){cmp obj.GetComponentInChildren(type);}if (cmp ! null){findResult.Add(scene.Substring(Application.dataPath.Length) Assets: obj.name);}}}//reopen current sceneEditorApplication.OpenScene(curScene);Debug.Log (finish);
}参考C#通过反射获取类中的所有字段和属性 - 董川民 (dongchuanmin.com)Unity-Find-Script-References 查找脚本的引用_子胤的博客-CSDN博客