unity编辑器扩展

Unity 编辑器扩展五 Handles 扩展Scene视图

2021-12-10  本文已影响0人  合肥黑

参考
Unity Editor 基础篇(四):Handles
【Unity 编辑器】扩展总结六:扩展Scene视图
官方文档 https://docs.unity.cn/cn/current/ScriptReference/Handles.RadiusHandle.html

一、Handles.RadiusHandle 半径控制器

如图,调节areaOfEffect值时,场景中会出现一个球体,展示这个值的影响范围。


image.png

EffectRadius.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EffectRadius : MonoBehaviour
{
    public float areaOfEffect = 1;
}

EffectRadiusEditor.cs

// Name this script "EffectRadiusEditor"
using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(EffectRadius))]
public class EffectRadiusEditor : Editor
{
    public void OnSceneGUI()
    {
        EffectRadius t = (target as EffectRadius);

        EditorGUI.BeginChangeCheck();
        float areaOfEffect = Handles.RadiusHandle(Quaternion.identity, t.transform.position, t.areaOfEffect);
        if (EditorGUI.EndChangeCheck())
        {
            Undo.RecordObject(target, "Changed Area Of Effect");
            t.areaOfEffect = areaOfEffect;
        }
    }
}

注意OnSceneGUI。视图的扩展主要通过OnSceneGUI()方法实现,因为场景扩展是基于场景对象的,所以可以选择不同的对象实现不同的场景视图操作。

二、示例

点选场景对象,显示该场景的坐标位置信息。


image.png
using UnityEngine;

public class SceneExt : MonoBehaviour
{

}

using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(SceneExt))]
public class SceneExtEditor : Editor
{
    //获取SceneExt脚本对象
    private SceneExt _target { get { return target as SceneExt; } }

    private void OnSceneGUI()
    {
        //操作句柄
        Handles.Label(_target.transform.position,
            _target.transform.name + " : " + _target.transform.position);

        //绘制GUI的内容必须要在BeginGUI、EndGUI的方法对中
        Handles.BeginGUI();
        //设置GUI绘制的区域
        GUILayout.BeginArea(new Rect(50, 50, 200, 200));
        GUILayout.Label("Scene 扩展练习");
        GUILayout.EndArea();
        Handles.EndGUI();
    }
}

注意:OnSceneGUI方法是通过Handles来绘制内容的,Handles类提供了大量用于绘制句柄的API。如果想要绘制GUI,则必须要在BeginGUI、EndGUI的方法对中。

有时候希望选择了场景对象后,点击场景窗口进行操作的时候,场景视图扩展依旧显示,这就需要设置场景对象的焦点为消极模式。在OnSceneGUI方法内调用如下API:

HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));
三、示例

该脚本挂载在场景对象身上

using UnityEngine;

public class SceneExt : MonoBehaviour
{
    public bool showLabel = true;
    public bool showLine = true;
    public bool showSlider = true;
    public bool showRadius = true;
    public bool showCircleHandleCap = true;
    public bool showSphereHandleCap = true; 
    public bool showGUI = true;

    public Vector3 sliderPos = Vector3.forward;
    public float areaRadius = 1;
    public float circleSize = 1;
}

该编辑器脚本放在Editor文件夹内

using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(SceneExt))]
public class SceneExtEditor : Editor
{
    //获取SceneExt脚本对象
    private SceneExt _target { get { return target as SceneExt; } }

    private void OnSceneGUI()
    {
        if (_target.showLabel)
        {
            //操作句柄,显示文本
            Handles.Label(_target.transform.position + Vector3.up * 0.5f, 
            _target.transform.name + " : " + _target.transform.position);
        }

        if (_target.showLine)
        {
            //修改句柄的颜色
            Handles.color = Color.yellow;
            //绘制一条线
            Handles.DrawLine(_target.transform.position, Vector3.up * 5);
        }

        if (_target.showSlider)
        {
            Handles.color = Color.red;
            //绘制一个可以沿着某个轴向的3D滑动条
            _target.sliderPos = Handles.Slider(_target.sliderPos, _target.transform.forward);
        }

        if (_target.showRadius)
        {
            Handles.color = Color.blue;
            //绘制一个半径控制手柄
            _target.areaRadius = Handles.RadiusHandle(Quaternion.identity, 
            _target.transform.position, _target.areaRadius);
        }

        if (_target.showCircleHandleCap)
        {
            //获取Y轴的颜色
            Handles.color = Handles.yAxisColor;
            //绘制一个圆环
            Handles.CircleHandleCap(0, _target.transform.position + Vector3.up * 2, 
            Quaternion.Euler(90, 0, 0), _target.circleSize, EventType.Repaint);
        }

        if (_target.showSphereHandleCap)
        {
            Handles.color = Color.green;
            //绘制一个球形
            Handles.SphereHandleCap(1, _target.transform.position, Quaternion.identity, 
            HandleUtility.GetHandleSize(_target.transform.position), EventType.Repaint);
        }

        if (_target.showGUI)
        {
            //绘制GUI的内容必须要在BeginGUI、EndGUI的方法对中
            Handles.BeginGUI();
            //设置GUI绘制的区域
            GUILayout.BeginArea(new Rect(50, 50, 200, 200));
            GUILayout.Label("Scene 扩展练习");
            GUILayout.EndArea();
            Handles.EndGUI();
        }
    }
}
上一篇 下一篇

猜你喜欢

热点阅读