【share】Unity插件界面編寫簡介


目錄

一、MenuItem --> Unity菜單選項擴展
二、CustomEditor --> 針對自定義Component的Inspector面板的擴展
三、DrawGizmo輔助顯示
四、OnGUI
五、EditorWindow --> 自定義一個窗口
六、ScriptableWizard --> 自定義一個對話框


 Unity提供了靈活的插件支持,供開發者自定義插件來提供開發效率,幾乎所有介紹到的支持都必須包含

using UnityEditor;

一般所屬腳本文件需要放在名為Editor的目錄下,如果不想將腳本文件放在Editor下,就需要用預編譯包含相關文件,否則編譯打包時會報錯

#if UNITY_EDITOR
    //...... Code In Editor
#endif

以下簡單介紹幾種常用擴展


一、MenuItem -->  Unity菜單選項擴展

* 必須寫在靜態方法之前

* 格式: [MenuItem("路徑",  isValidateFunction , 優先級)]

  路徑 --> 用"/"分割路徑層級,可支持添加快捷鍵(語法細節不深入)

  isValidateFunction -->  是否有驗證函數,比如[MenuItem("Assets\OutputVertexCount", true)],Unity將自動執行一個名為ValidateOutputVertexCount(Validate+菜單選項名)的函數,返回值為true則該菜單項才會被啟用

  優先級 --> 指在彈出的菜單中顯示排序的優先級,小前大后(系統自帶選項有自己的優先級數值,這個沒有深究其數值范圍,一般相隔100內的選項會成組,並被用橫線隔開,這個制作插件的時候自由發揮,無需在意太多細節),默認在菜單最后

簡單說就是編輯器中的右鍵菜單擴展,包括以下幾類

1) Assets

[MenuItem("Assets/NPC/生成",false, 1)]
public static void GeneratePrefab()
{
     //.......//      
}

效果如圖:

 以及 

2) GameObject

[MenuItem("GameObject/UITemplate/Creat To Prefab", false, 11)]
static void CreatToPrefab(MenuCommand menuCommand)
{
    //.......//
}

效果類似Assets,不同的是可在Hierarchy層級面板彈出右鍵菜單中看到添加的選項

3) 其他字符串

直接在編輯器上層菜單欄添加

4) Selection

在函數中善用Unity自帶的Selection類,Selection.Objects用來指帶目前被選中的對象(一個或多個),進行邏輯操作。詳細用法參照


 

二、CustomEditor --> 針對自定義Component的Inspector面板的擴展

在開發中經常遇到自己寫了一個腳本Component,附帶了一些屬性和邏輯,想要自定義這個Component在Inspector面板的一些操作,就要用到CustomEditor擴展

用法很簡單,如下:

//Editor類 --> 下面這句聲明了專門是為MyComponent定制的
[CustomEditor(typeof(MyComponent))]
public class MyComponentEditor : Editor
{
    //Inspector面板的顯示繪制
    public void OnInspectorGUI()
    {
           //........//
    }

    //還可以自定義scene視圖的顯示繪制
    public void OnSceneGUI()
    {
           //........//
    }
}

//MyComponent類的實現
public class MyComponent: MonoBehaviour
{
    //......//
}

MyComponent是我們自己實現的功能類,當Scene視圖中某個GameObject被選中,且該GameObject有MyComponent這個控件,則其對應的MyComponentEditor就會接管編輯器的顯示,如:

1) OnInspectorGUI --> 控制Inspector面板的繪制

如果需要顯示默認的Inspcetor,則加一句  DrawDefaultInspector() 就行了

繪制GUI主要依靠幾個類:

GUI, GUILayout, EditorGUILayout, EditorGUI 用於繪制按鈕、文字,單選框,滾動條,圖片之類的,GUI與Editor大體是一樣的

GUIStyle 風格設置

建議可以在需要繪制UI的時候去查一下手冊,看看有什么可以用到的控件。

2) OnSceneGUI --> 控制Scene視圖窗口的消息處理

這個函數可以接收Scene視窗中發生的事件 --> UnityEngine.Event

public void OnSceneGUI()
{
     //可獲取當前事件
     UnityEngine.Event e = UnityEngine.Event.current;
    
     //事件類型(常見有MouseUp/Down, KeyUp/Down, Layout, Used, Repaint等)
     UnityEngine.EventType EType = e.type;

     //根據事件類型,在OnSceneGUI做對應的顯示處理
     //以下判斷識別鼠標按下,移動,或者拖動
             if (EType == UnityEngine.EventType.MouseDown
            || EType == UnityEngine.EventType.MouseMove
            || EType == UnityEngine.EventType.MouseDrag)
        {
            //Event.current中有詳細的狀態信息
            //如下面獲取了某些按鍵的狀態,進行邏輯排除
            if (UnityEngine.Event.current.alt                   //按着alt鍵位     忽略
                || UnityEngine.Event.current.button == 2        //中鍵            忽略
                )
            {
                return;
            }

            //下面代碼在獲取鼠標點擊的位置
            Ray worldRay = HandleUtility.GUIPointToWorldRay(UnityEngine.Event.current.mousePosition);
            RaycastHit hitInfo;
            if (Physics.Raycast(worldRay, out hitInfo))
            {
                Vector2 Target = new Vector2(hitInfo.point.x, hitInfo.point.z);
            }
    }

    //調用Use()表示該事件已經被處理過了,不會再傳給其他模塊
    UnityEngine.Event.current.Use();
}

Editor的其他接口

3) Unity內置控件的Editor

Unity已有的內置空間也可以做Editor擴展,如Material有MaterialEditor,這塊沒嘗試過...

4) Attributes --- 常見屬性標簽語法

我們會常常用到一些標簽式的語法,修飾在某個函數或者類前,用來指代這個函數或者類的一些屬性,MenuItem就是其中一種,常見的還有:

//表現MyCompoent需要用到MeshFilter這個Component,添加MyComponent的時候,如果同級沒有MeshFilter,會自動添加
[RequireComponent(typeof(MeshFilter))]
public class MyComponent : MonoBehaviour {
}

//表示這個Component在Edit模式下也會運行,但注意其Update只有在場景中的GameObject有發生變化的時候才會調用
[ExecuteInEditMode]
public class MyComponent: MonoBehaviour{
}


public class MyComponent:MonoBehaviour{
        //序列化屬性,可在Inspector見到(即使是private),並操作
        [SerializeField]
    private bool hasHealthPotion = true;

        //不在Inspcetor顯示這個屬性
        [HideInInspector]
        public int p = 5;
}

延伸閱讀

 


 

三、DrawGizmo輔助顯示

重載MonoBehaviour的OnDrawGizmos可以用來繪制在場景輔助顯示,如Line(線段), Mesh(網格), Ray(射線), Sphere(球形)等。

具體使用Gizmos.DrawXXX系列函數,參考

需注意Scene視圖默認顯示Gizmos繪制,如果要在Game視圖顯示Gizmos,需選中如圖按鈕

 

項目在調試玩家自動戰斗AI、玩家搖桿移動、布怪、刷阻擋,都用到了Gizmos這個功能,好處是調試起來較為直觀


 

四、OnGUI

重載MonoBehaviour的OnGUI可以用來在場景視圖上繪制簡單的UI界面

項目目前使用OnGUI繪制幀率,內存等游戲基本信息


 

五、EditorWindow --> 自定義一個窗口

EditorWindow用於創建一個獨立窗口,當你在制作一個功能較雜且較為獨立的插件的時候或許會用到。用法也十分簡單,編寫一個繼承EditorWindow的類就行了

public class ConsoleEditorWindow : EditorWindow
{
  //重載OnGUI,其繪制的UI不是在Scene視圖中,而是在打開的EditorWindow上
  void OnGUI()
  {
  }
}

繪制的函數也是使用GUILayout,EditorGUILayout等一系列API,不在贅述。

另外你需要通過編寫一個帶MenuItem的Attribute或者其他什么函數,來作為打開這個EditorWindow的入口。

EditorWindow中包含一些比較常用的函數,如:

1) Show ---> 顯示窗口,功能類似的還有ShowPopup,ShowAsDropDown等,不同的是這些接口應用了一些固定的外觀Style

2) Repaint ---> 重繪,你在OnGUI中處理了一些邏輯,需要重繪來理解更新UI的,可以調用這個

3) Close --> 關閉窗口

4) OnFocus/OnLostFocus --> 窗口得到或者失去焦點,也挺有用的

參考


 

六、ScriptableWizard --> 自定義一個對話框

由ScripttableWizard派生出來的類主要干的事情就是類似你安裝一個軟件時,不停的彈出引導安裝的對話框(下一步取消下一步取消下一步取消下一步取消)的事情一樣。

不過ScripttableWizard目前只支持兩個操作按鈕(Create、Other)

有用到類似功能的朋友可以去看看


 

結語:

本文主要簡介了下Unity編寫插件的幾種方式,沒有具體講到某個插件例子的編寫。實際編寫遇到的問題大部分是因為對API的不熟悉,只能通過多多Google,查找手冊來一步步完成自己的插件,這是個繁瑣的過程。

希望讀完本文,讀者在拿到一個別人編寫的插件時,也能大體想象出插件的代碼結構,快速找出插件的關鍵代碼,為自己所用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM