unity-編輯器擴充套件
阿新 • • 發佈:2019-02-18
- unity編輯器擴充套件很方便,可以省掉很多製作其他工具的時間(比如技能編輯器,特效編輯器等,都是資料結構的匯入匯出)
- 可以直接在 Scene 、Inspector 或者新建一個 Window 中編輯
1、Inspector
在 Inspector 中最簡單的就是直接把指令碼中的成員變數設定為 public,直接就可以在顯示出來編輯。
public class Actor : MonoBehaviour { #region public member public Vector3 lookAtPoint = Vector3.zero; public
針對指令碼定製編輯panel
- 新建一個 Editor 資料夾(啥地方都行),unity會自動監測,自動生成vs的工程目錄結構。
- 在 Editor 資料夾下create個編輯器指令碼 ActorEditor.cs (可以隨意,一般以Editor為字尾),指令碼繼承 Editor
using UnityEngine; using UnityEngine.UI; using System.Collections; using UnityEditor; [CustomEditor(typeof(Actor))] //編輯對應的指令碼 public class ActorEditor : Editor { //private string mPath1 = ""; private Actor mActor; public override void OnInspectorGUI() { Actor t = (Actor)target;
2、Window
同樣也是create個指令碼 TestDrag 丟在 Editor 資料夾下。TestDrag 繼承 EditorWindow ,寫個靜態方法 Init 上面用屬性標註 [MenuItem("MyWindow/TestDrag")]
,意思就是會在選單欄 MyWindow/TestDrag中點選觸發彈出TestDrag 的編輯 window,然後重寫 OnGUI() 方法具體定製顯示需要編輯的東東
using UnityEngine;
using System.Collections;
using UnityEditor;
public class TestDrag : EditorWindow
{
string path;
Rect rect;
bool groupEnabled = true;
string myString = "Hello World";
bool myBool = true;
float myFloat = 1.23f;
[MenuItem("MyWindow/TestDrag")] //觸發彈出TestDrag window的按鈕
static void Init()
{
EditorWindow.GetWindow(typeof(TestDrag));
}
void OnGUI() //繪製window
{
EditorGUILayout.LabelField("路徑", EditorStyles.boldLabel);
//獲得一個長300的框
rect = EditorGUILayout.GetControlRect(GUILayout.Width(300));
//將上面的框作為文字輸入框
path = EditorGUI.TextField(rect, path);
//如果滑鼠正在拖拽中或拖拽結束時,並且滑鼠所在位置在文字輸入框內
if ((Event.current.type == EventType.DragUpdated
|| Event.current.type == EventType.DragExited)
&& rect.Contains(Event.current.mousePosition))
{
//改變滑鼠的外表
DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
if (DragAndDrop.paths != null && DragAndDrop.paths.Length > 0)
{
path = DragAndDrop.paths[0];
}
}
//---------
GUILayout.Label("Base Settings", EditorStyles.boldLabel);
myString = EditorGUILayout.TextField("Text Field", myString);
groupEnabled = EditorGUILayout.BeginToggleGroup("Optional Settings", groupEnabled);
myBool = EditorGUILayout.Toggle("Toggle", myBool);
myFloat = EditorGUILayout.Slider("Slider", myFloat, -3, 3);
EditorGUILayout.EndToggleGroup();
}
}
3、Scene
同樣也是create個指令碼 SceneRealTimeFocusEditor 丟在 Editor 資料夾下。
在場景中顯示一些按鈕、文字什麼的
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEditor;
/// <summary>
/// Scene中的按鈕擴充套件:
/// </summary>
[CustomEditor(typeof(MonoBehaviour), true)]
public class SceneRealTimeFocusEditor : Editor
{
public void OnEnable()
{
active = false;
}
public void OnDisable()
{
active = false;
}
private bool active = false;
void OnSceneGUI()
{
GameObject[] gos = Selection.gameObjects;
if (gos != null)
//if (Selection.activeTransform != null)
{
Handles.BeginGUI();
GUILayout.BeginArea(new Rect(0, 0, 200, 200));
if (!active)
{
if (GUILayout.Button("Active Real Time Trace", GUILayout.Height(30)))
{
active = true;
}
}
else
{
if (GUILayout.Button("Close Real Time Trace", GUILayout.Height(30)))
{
active = false;
}
}
GUILayout.EndArea();
Handles.EndGUI();
if (active)
{
SceneView.lastActiveSceneView.pivot = gos[0].transform.position;
//SceneView.lastActiveSceneView.pivot = Selection.activeTransform.position;
SceneView.lastActiveSceneView.Repaint();
}
}
}
}
4、附上一個場景物件實時追蹤
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Text;
/// <summary>
/// 實時顯示場景中的物件
/// </summary>
public class SceneEditorWindow : EditorWindow
{
RaycastHit _hitInfo;
SceneView.OnSceneFunc _delegate;
static SceneEditorWindow _windowInstance;
private GameObject[] mSelectObjs = null;
[MenuItem("MyWindow/Scene Editor #`")] //快捷方式:shift+`
static void Init()
{
if (_windowInstance == null)
{
_windowInstance = EditorWindow.GetWindow(typeof(SceneEditorWindow)) as SceneEditorWindow;
_windowInstance._delegate = new SceneView.OnSceneFunc(OnSceneFunc);
SceneView.onSceneGUIDelegate += _windowInstance._delegate;
}
}
void OnEnable()
{
}
void OnDisable()
{
}
void OnDestroy()
{
if (_delegate != null)
{
SceneView.onSceneGUIDelegate -= _delegate;
}
}
void OnSelectionChange()
{
mSelectObjs = Selection.gameObjects;
}
void OnGUI()
{
EditorGUILayout.LabelField("All Selected Objects", EditorStyles.boldLabel);
if (mSelectObjs != null)
{
for (int i = 0; i < mSelectObjs.Length; ++i)
{
EditorGUILayout.BeginHorizontal();
GameObject go = mSelectObjs[i];
EditorGUILayout.Vector3Field(go.name, go.transform.position);
EditorGUILayout.EndHorizontal();
}
}
}
void OnInspectorGUI()
{
Debug.Log("OnInspectorGUI");
}
static public void OnSceneFunc(SceneView sceneView)
{
_windowInstance.CustomSceneGUI(sceneView);
}
void CustomSceneGUI(SceneView sceneView)
{
Camera cameara = sceneView.camera;
Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
if (Physics.Raycast(ray, out _hitInfo, 10000, -1))
{
//Debug.DrawRay(ray.origin, ray.direction, Color.yellow);
Vector3 origin = _hitInfo.point;
origin.y += 100;
if (Physics.Raycast(origin, Vector3.down, out _hitInfo))
{
Handles.color = Color.yellow;
Handles.DrawLine(_hitInfo.point, origin);
float arrowSize = 1;
Vector3 pos = _hitInfo.point;
Quaternion quat;
Handles.color = Color.green;
quat = Quaternion.LookRotation(Vector3.up, Vector3.up);
Handles.ArrowCap(0, pos, quat, arrowSize);
Handles.color = Color.red;
quat = Quaternion.LookRotation(Vector3.right, Vector3.up);
Handles.ArrowCap(0, pos, quat, arrowSize);
Handles.color = Color.blue;
quat = Quaternion.LookRotation(Vector3.forward, Vector3.up);
Handles.ArrowCap(0, pos, quat, arrowSize);
//Handles.DrawLine(pos + new Vector3(0, 3, 0), pos);
}
}
SceneView.RepaintAll();
}
}