unity 編輯器擴展簡單入門 通過使用編輯器擴展,我們可以對一些機械的操作實現自動化,而不用使用額外的環境,將工具與開發環境融為一體;並且,編輯器擴展也提供GUI庫,來實現可視化操作;編輯器擴展甚至也可以“補充”IDE缺失的一些內容,讓IDE更加人性化。 主要內容 MenuItem無界面操作 視窗 ...
unity 編輯器擴展簡單入門
通過使用編輯器擴展,我們可以對一些機械的操作實現自動化,而不用使用額外的環境,將工具與開發環境融為一體;並且,編輯器擴展也提供GUI庫,來實現可視化操作;編輯器擴展甚至也可以“補充”IDE缺失的一些內容,讓IDE更加人性化。
主要內容
- MenuItem無界面操作
- 視窗
- 優化內置操作
- 簡單工具視窗
- Gizmos改造場景顯示
一、MenuItem無界面操作
在 assets
文件夾下創建Editor
文件夾,創建一個新的c#
腳本;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class BaseTest : MonoBehaviour
{
[MenuItem("德瑪/第一個擴展")]
static void debugLog()
{
Debug.Log("我是一個menuItem");
}
}
如圖,這是我們第一個創建的擴展。
此時,如果我們需要獲得一個當前場景選中的物品,則
需要通過Selection
。將代碼拷貝到當前創建的類裡面:
// 設置第二個參數
[MenuItem("德瑪/two", false)]
static void testSecondParam()
{
Vector3 p = Selection.activeTransform.position;
Vector3 v3 = new Vector3(p.x+1, p.y, p.z);
Instantiate(Selection.activeTransform, v3, Quaternion.identity);
}
[MenuItem("德瑪/two", true)]
static bool testSecondParam2()
{
return Selection.activeGameObject != null;
}
通過這段代碼,我們可以創建一個只有選擇了一個場景物體,才會激活的按鈕。
二、視窗
創建視窗需要通過EditorWindow
作為基類,還是MenuItem
為入口創建;
using UnityEngine;
using System.Collections;
using UnityEditor; //註意要引用
public class MyWindow : EditorWindow
{
[MenuItem("德瑪/Window/NormalWindow")]//在unity菜單Window下有MyWindow選項
static void NormalWindow()
{
windowType = 1;
MyWindow myWindow = (MyWindow)EditorWindow.GetWindow(typeof(MyWindow), true, "德瑪標題", true);//創建視窗
myWindow.Show();//展示
}
public void Awake()
{
//在資源中讀取一張貼圖
texture = Resources.Load("1") as Texture;
}
//繪製視窗時調用
void OnGUI()
{
EditorGUILayout.LabelField("選中");
EditorGUILayout.LabelField(EditorWindow.focusedWindow.ToString());
EditorGUILayout.LabelField("劃入");
EditorGUILayout.LabelField(EditorWindow.mouseOverWindow.ToString());
}
//更新
void Update()
{
}
void OnFocus()
{
Debug.Log("當視窗獲得焦點時調用一次");
}
void OnLostFocus()
{
Debug.Log("當視窗丟失焦點時調用一次");
}
void OnHierarchyChange()
{
Debug.Log("當Hierarchy視圖中的任何對象發生改變時調用一次");
}
void OnProjectChange()
{
Debug.Log("當Project視圖中的資源發生改變時調用一次");
}
void OnInspectorUpdate()
{
//Debug.Log("視窗面板的更新");
//這裡開啟視窗的重繪,不然視窗信息不會刷新
this.Repaint();
}
void OnSelectionChange()
{
//當視窗出去開啟狀態,並且在Hierarchy視圖中選擇某游戲對象時調用
foreach (Transform t in Selection.transforms)
{
//有可能是多選,這裡開啟一個迴圈列印選中游戲對象的名稱
Debug.Log("OnSelectionChange" + t.name);
}
}
void OnDestroy()
{
Debug.Log("當視窗關閉時調用");
}
}
將上面的代碼放入Editor
目錄下,通過德瑪/Window/NormalWindow
可以打開視窗。
EditorWindow.focusedWindow
獲取當前焦點視窗;
EditorWindow.mouseOverWindow
獲取當前滑鼠劃入的視窗;
各種生命周期函數均有列印,自行理會。
void OnInspectorUpdate()
{
//Debug.Log("視窗面板的更新");
//這裡開啟視窗的重繪,不然視窗信息不會刷新
this.Repaint();
}
這段代碼可以保證實時刷新顯示。
三、優化內置操作
當路徑放入GameObject
的時候,會出現在右鍵菜單裡面;
[MenuItem("GameObject/德瑪/德瑪Custom Game Object", false, 10]
註解
當然,除了在Editor
目錄下添加各種擴展以外,我們可以通過給項目腳本添加註解的方式,來優化編輯器顯示;
比如通過添加類似於Component
的方式,來優化腳本的添加方式,點擊後會直接將腳本添加到場景物體上。
將[RequireComponent(typeof(Rigidbody))]
放入類頭。我們將下麵腳本放入到Assets/Scripts
目錄下麵。
using UnityEngine;
// 通過編輯器的Component菜單添加腳本
[RequireComponent(typeof(Rigidbody))]
[HelpURL("https://docs.unity3d.com/ScriptReference/HelpURLAttribute.html")]
[AddComponentMenu("德瑪/添加德瑪腳本")]
public class ContextTesting : MonoBehaviour
{
[Header("屬性標題")]
[Multiline(3)]
public string name2;
[Space(100)]
[Tooltip("用於設置性別")]
public string sex;
[HideInInspector]
public int p = 5;
[Range(1, 100)]
[Tooltip("Health value between 0 and 100.")]
public int health = 0;
/// Add a context menu named "Do Something" in the inspector
/// of the attached script.
/// 給當前腳本添加右鍵內容
[ContextMenu("德瑪西亞")]
void DoSomething()
{
Debug.Log("德瑪西亞列印");
}
// 給屬性添加右鍵
[ContextMenuItem("重置屬性為空", "ResetBiography")]
public string playerBiography = "";
void ResetBiography()
{
playerBiography = "";
}
}
我們發現,我們可以想組件一樣的添加腳本了!
在Inspector
目錄我們也註意到當前腳本屬性的顯示也發生了變化;
在Inspector
上,我們也多出來一個Rigidbody
組件。
美化項目腳本的屬性顯示
在Assets/Scripts
下麵創建MyPlayer
using UnityEngine;
using System.Collections;
public class MyPlayer : MonoBehaviour
{
public int armor = 100;
public int attack = 100;
public GameObject equipment;
}
在Editor
下麵創建MyPlayerEditor
:
using UnityEngine;
using UnityEditor;
using System.Collections;
[CustomEditor(typeof(MyPlayer))]
public class MyPlayerEditor : Editor
{
SerializedProperty attack;
void OnEnable()
{
attack = serializedObject.FindProperty("attack");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.IntSlider(attack, 0, 100, new GUIContent("攻擊力"));
ProgressBar(attack.intValue / 100, "攻擊力");
serializedObject.ApplyModifiedProperties();
}
private void ProgressBar(float value, string label)
{
Rect rect = GUILayoutUtility.GetRect(18, 18, "TextField");
EditorGUI.ProgressBar(rect, value, label);
EditorGUILayout.Space();
}
}
觀察Inspector
簡單工具視窗
一個簡單的確認視窗
using UnityEngine;
using UnityEditor;
public class MyEditorUtilityTest : ScriptableObject
{
[MenuItem("德瑪/自定義對話框")]
static void CreateWizard()
{
if (EditorUtility.DisplayDialog("對話框標題", "對話框的消息", "OK", "取消"))
{
Debug.Log("OK被點擊");
}
else
{
Debug.Log("您沒有點擊OK");
}
}
}
顯示如下
Gizmos改造場景顯示
我們可以改造物體在場景中的顯示;
如下代碼
其他
通過上面的案例,我們大致瞭解了Unity編輯器擴展的基本內容,通過這些已經可以實現很多功能了!
倉庫地址:
https://github.com/wyy5552/unityEditor