通过反射调用Unity编辑器提供的各种功能

Posted sifenkesi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过反射调用Unity编辑器提供的各种功能相关的知识,希望对你有一定的参考价值。

Unity编辑器功能丰富易上手,其实编辑器提供的大多数菜单操作,在代码里面都是能够找到对应接口的,但是这些接口都没有对我们开放,怎么办?

很简单,直接使用反射调用即可。

首先使用Reflector或ILSpy将UnityEditor和UnityEngine进行反编译(有源码的可以直接查看源码更好),然后在里面找你需要的功能即可,unity的底层代码命名是非常规范的,多数功能都能直观的找到:

  下图中是Hierarchy视图中一些操作函数,怎么样,是不是很直观:

技术分享图片

  怎么调用这些函数呢,下面展示了static function和member function的调用方式,参考着用即可:

using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;

public class DIYEditor : EditorWindow
{
    private static EditorWindow window;

    [MenuItem("DIY/SelfEditor")]
    public static void Execute()
    {
        if (window == null)
            window = (DIYEditor)GetWindow(typeof(DIYEditor));
        window.minSize = new Vector2(300, 300);
        window.Show();
    }

    private void OnGUI()
    {
        if (GUILayout.Button("Project.DuplicateSelectedAssets", GUILayout.Height(50)))
        {
            ProjectDuplicate();
        }

        if (GUILayout.Button("Hierarchy.DuplicateSelectedAssets", GUILayout.Height(50)))
        {
            HierarchyDuplicate();
        }

        if (GUILayout.Button("GameView.SizeSelection", GUILayout.Height(50)))
        {
            HierarchyDuplicate();
        }
    }

    // 拷贝Project视图中的某个Prefab
    private void ProjectDuplicate()
    {
        var gvWndType = typeof(Editor).Assembly.GetType("UnityEditor.ProjectWindowUtil");

        var duplicate = gvWndType.GetMethod("DuplicateSelectedAssets",
            System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);

        duplicate.Invoke(null, null);
    }

    // 拷贝Hierarchy视图中的某个Prefab,优点:(1)速度快(2)保持引用关系。在代码中Instantiate会丢失引用,并且速度很慢
    private void HierarchyDuplicate()
    {
        var gvWndType = typeof(Editor).Assembly.GetType("UnityEditor.SceneHierarchyWindow");
        var gvWnd = EditorWindow.GetWindow(gvWndType);
        var duplicateSelectedFunc = gvWndType.GetMethod("DuplicateGO",
            System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);

        duplicateSelectedFunc.Invoke(gvWnd, null);
    }

    // 手动设置Game视图的分辨率,可以用来在编辑态下动态改变runtime分辨率
    public static void SetGameView(int index)
    {
        var gvWndType = typeof(Editor).Assembly.GetType("UnityEditor.GameView");
        var gvWnd = EditorWindow.GetWindow(gvWndType);
        var SizeSelectionCallback = gvWndType.GetMethod("SizeSelectionCallback",
            System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
        SizeSelectionCallback.Invoke(gvWnd, new object[] { index, null });
    }
}

   总之,编辑器功能强大,皆能为我所用,方法就是反射,以上!

以上是关于通过反射调用Unity编辑器提供的各种功能的主要内容,如果未能解决你的问题,请参考以下文章

Unity 自定义编辑器窗口输入控件,用于反射确定的类型

unity 贴图

Unity3d和Android之间互相调用

说说反射的用途及实现

Unity3D热更新技术点——ToLua

unity3d使用协程应该注意啥