經過反射調用Unity編輯器提供的各類功能

Unity編輯器功能豐富易上手,其實編輯器提供的大多數菜單操做,在代碼裏面都是可以找到對應接口的,可是這些接口都沒有對咱們開放,怎麼辦?編輯器

很簡單,直接使用反射調用便可。函數

首先使用Reflector或ILSpy將UnityEditor和UnityEngine進行反編譯(有源碼的能夠直接查看源碼更好),而後在裏面找你須要的功能便可,unity的底層代碼命名是很是規範的,多數功能都能直觀的找到:spa

  下圖中是Hierarchy視圖中一些操做函數,怎麼樣,是否是很直觀:code

  怎麼調用這些函數呢,下面展現了static function和member function的調用方式,參考着用便可:blog

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)))
        {
            SetGameView(1);
        }
    }

    // 拷貝Project視圖中的某個Prefab
    private void ProjectDuplicate()
    {
        var type = typeof(Editor).Assembly.GetType("UnityEditor.ProjectWindowUtil");

        var duplicate = type.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 type = typeof(Editor).Assembly.GetType("UnityEditor.SceneHierarchyWindow");
        var window = EditorWindow.GetWindow(type);
        var duplicateSelectedFunc = type.GetMethod("DuplicateGO",
            System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);

        duplicateSelectedFunc.Invoke(window, null);
    }

    // 手動設置Game視圖的分辨率,能夠用來在編輯態下動態改變runtime分辨率
    public static void SetGameView(int index)
    {
        var type = typeof(Editor).Assembly.GetType("UnityEditor.GameView");
        var window = EditorWindow.GetWindow(type);
        var SizeSelectionCallback = type.GetMethod("SizeSelectionCallback",
            System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
        SizeSelectionCallback.Invoke(window, new object[] { index, null });
    }
}

   總之,編輯器功能強大,皆能爲我所用,方法就是反射,以上!接口

相關文章
相關標籤/搜索