您的位置:首页 > 移动开发 > Unity3D

Unity3D 场景编辑器扩展学习笔记-EditorWindow

2014-02-19 18:09 519 查看
今天可以说是有点成果了,可喜可贺~先上图



本节内容涉及到的类: EditorWindow, Physics, Handles, Camera, SceneView.

Editor类虽然可以使用OnSceneGUI来进行Scene视图里的各种定制操作,但是只能针对特定类型的脚本进行。如果想实现种怪这种编辑器常见需求,实现起来超级别扭。我尝试着基于Editor类来实现这个操作,发现除了在Inspector里锁住当前组件的视图外,没什么好方法了:创建一个空对象,放一个特定的类,实现一个特定的Editor,再每次编辑场景数据时手动锁定Inspector....想想都吐血了。

因此不可避免的寻求其他解决方案:EditorWindow

EditorWindowNamespace:
UnityEditor
Parent class: ScriptableObject

Description
Derive from this class to create an editor window.

Create your own custom editor window that can float free or be docked as a tab, just like the native windows in the Unity interface.

关于EditorWindow的使用,U3D还是有一些基本例子的,今天我要谈的是关于SceneView的操作。

SceneView.onSceneGUIDelegate 该函数为定制提供了可能性,上代码先。

using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Text;

public class SceneEditorWindow : EditorWindow {

RaycastHit _hitInfo;
SceneView.OnSceneFunc _delegate;
static SceneEditorWindow _windowInstance;

[MenuItem("Window/Scene Editor #`")]
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 OnGUI()
{
}

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



发现没啥可讲的了。。因为有之前GUILayout和Handles的知识后,其实只需要知道一个流程性的代码就行了。

而且EditorWindow的基本使用,U3D文档里已经有很充分的例子。

有一点需要注意,SceneView.RepaintAll(); 根据观察,SceneView在没有任何操作时,FPS估计是1,鼠标移动不会触发场景重绘,但是 onSceneGUIDelegate
确是一直在调用,所以加上这个之后,操作的反馈就变成实时的了,这会带来效率损耗---如果不影响操作的话,不用管。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  编辑器 unity3d 扩展