【Unity】编辑器小教程

写在前面

Unity最强大的地方之一是它扩展性非常强的编辑器。Unite Europe 2016上有一个视频专门讲编辑器编程的:

这里大概记录一下里面的关键点。

场景一

关注点

  • 绘制重要区域,Gizmos.DrawXXX
  • OnDrawGizmos和OnDrawGizmosSelected回调函数
  • 点击Gizmos按钮就可以在Game视图也看到线框了

这里写图片描述

    // OnDrawGizmos()会在编辑器的Scene视图刷新的时候被调用
    // 我们可以在这里绘制一些用于Debug的数据
    void OnDrawGizmos()
    {
        Gizmos.color = new Color( 1f, 0f, 0f, 1f );
        Gizmos.DrawWireCube( transform.position + BoxCollider.center, BoxCollider.size );

        Gizmos.color = new Color( 1f, 0f, 0f, 0.3f );
        Gizmos.DrawCube( transform.position + BoxCollider.center, BoxCollider.size );
    }

    // OnDrawGizmosSelect()类似于OnDrawGizmos(),它会在当该组件所属的物体被选中时被调用
    void OnDrawGizmosSelected()
    {
        Gizmos.color = new Color( 1f, 1f, 0f, 1f );
        Gizmos.DrawWireCube( transform.position + BoxCollider.center, BoxCollider.size );

        Gizmos.color = new Color( 1f, 1f, 0f, 0.3f );
        Gizmos.DrawCube( transform.position + BoxCollider.center, BoxCollider.size );
    }

场景二

关注点

  • 组织面板上的参数,添加滑动条、Header、空白等

这里写图片描述

    [Space( 10 )]
    public float MaximumHeight;
    public float MinimumHeight;

    [Header( "Safe Frame" )]
    [Range( 0f, 1f )]
    public float SafeFrameTop;
    [Range( 0f, 1f )]
    public float SafeFrameBottom;

注意到上面面板的最小面有个Camera Height,调节它可以改变摄像机的高度。这个改变是可以发生在编辑器模式下的,而且也不需要脚本添加ExecuteInEditor。这是通过实现自定义的Editor脚本来实现的:

using UnityEngine;
using UnityEditor;
using System.Collections;

// 我们可以通过为一个类定义它的Editor类型的[CustomEditor]来自定义该类的绘制界面
// 这需要把这个文件放在Editor目录下
[CustomEditor( typeof( GameCamera ) )]
public class GameCameraEditor : Editor 
{
    GameCamera m_Target;

    // 重载OnInspectorGUI()来绘制自己的编辑器
    public override void OnInspectorGUI()
    {
        // target可以让我们得到当前绘制的Component对象
        m_Target = (GameCamera)target;

        // DrawDefaultInspector告诉Unity按照默认的方式绘制面板,这种方法在我们仅仅想要自定义某几个属性的时候会很有用
        DrawDefaultInspector();
        DrawCameraHeightPreviewSlider();  
    }

    void DrawCameraHeightPreviewSlider()
    {
        GUILayout.Space( 10 );

        Vector3 cameraPosition = m_Target.transform.position;
        cameraPosition.y = EditorGUILayout.Slider( "Camera Height", cameraPosition.y, m_Target.MinimumHeight, m_Target.MaximumHeight );

        if( cameraPosition.y != m_Target.transform.position.y )
        {
            // 改变状态前,使用该方法来记录操作,以便之后Undo
            Undo.RecordObject( m_Target, "Change Camera Height" );
            m_Target.transform.position = cameraPosition;
        }
    }
}

场景三

关注点

  • 自定义绘制List对象
  • 使用serializedObject来修改参数的话Unity会自动有各种帮助函数,例如自动添加Undo功能
  • 如果直接修改参数的话,需要使用EditorUtility.SetDirty来告诉Unity需要保存数据
  • BeginChangeCheck()和EndChangeCheck()会检测它们之间的GUI有没有被修改,如果修改了的话可以据此修改参数
  • Undo.RecordObject可以为下一步修改添加Undo/Redo
  • EditorUtility.DisplayDialog可以打开内置对话框

这里写图片描述

  1. 首先在面板上隐藏默认的List绘制方法,使用HideInInspector隐藏属性:

    public class PistonE03 : MonoBehaviour 
    {
        public float Speed;
        public Vector3 AddForceWhenHittingPlayer;
    
        //We are hiding this in the inspector because we want to draw our own custom
        //inspector for it.
        [HideInInspector]
        public List<PistonState> States = new List<PistonState>();
        ......
  2. 为了让PistonState可以显示在面板上,需要序列化PistonState:

    //[System.Serializable] tells unity to serialize this class if 
    //it's used in a public array or as a public variable in a component
    [System.Serializable]
    public class PistonState 
    {
        public string Name;
        public Vector3 Position;
    }
  3. 实现自定义的绘制方程:

    [CustomEditor( typeof( PistonE03 ) )]
    public class PistonE03Editor : Editor 
    {
        PistonE03 m_Target;
    
        public override void OnInspectorGUI()
        {
            m_Target = (PistonE03)target;
    
            DrawDefaultInspector();
            DrawStatesInspector();        
        }
    
        //Draw a beautiful and useful custom inspector for our states array
        void DrawStatesInspector()
        {
            GUILayout.Space( 5 );
            GUILayout.Label( "States", EditorStyles.boldLabel );
    
            for( int i = 0; i < m_Target.States.Count; ++i )
            {
                DrawState( i );
            }
    
            DrawAddStateButton();
        }
    DrawDefaultInspector:先绘制默认的,DrawStatesInspector:自定义绘制面板函数。
    
  4. DrawState函数:

     void DrawState( int index )
    {
        if( index < 0 || index >= m_Target.States.Count )
        {
            return;
        }
    
        // 在我们的serializedObject中找到States变量
        // serializedObject允许我们方便地访问和修改参数,Unity会提供一系列帮助函数。例如,我们可以通过serializedObject来修改组件值,而不是直接修改,Unity会自动创建Undo和Redo功能
        SerializedProperty listIterator = serializedObject.FindProperty( "States" );
    
        GUILayout.BeginHorizontal();
        {
            // 如果是在实例化的prefab上修改参数,我们可以模仿Unity默认的途径来让修改过的而且未被Apply的值显示成粗体
            if( listIterator.isInstantiatedPrefab == true )
            {
                //The SetBoldDefaultFont functionality is usually hidden from us but we can use some tricks to
                //access the method anyways. See the implementation of our own EditorGUIHelper.SetBoldDefaultFont
                //for more info
                EditorGUIHelper.SetBoldDefaultFont( listIterator.GetArrayElementAtIndex( index ).prefabOverride );
            }
    
            GUILayout.Label( "Name", EditorStyles.label, GUILayout.Width( 50 ) );
    
            // BeginChangeCheck()和EndChangeCheck()会检测它们之间的GUI有没有被修改
            EditorGUI.BeginChangeCheck();
            string newName = GUILayout.TextField( m_Target.States[ index ].Name, GUILayout.Width( 120 ) );
            Vector3 newPosition = EditorGUILayout.Vector3Field( "", m_Target.States[ index ].Position )
  • 36
    点赞
  • 135
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
Unity编辑器拓展教程是一种自定义Unity编辑器功能的方法。通过扩展Unity编辑器,我们可以为开发者提供更方便、高效的开发环境。下面是一个简单的Unity编辑器拓展教程: 1. 创建一个自定义编辑器窗口:首先,我们可以创建一个新的C#脚本文件,并继承自EditorWindow类。在这个脚本中,我们可以自定义一个窗口,并在该窗口中进行编辑器拓展的操作。 2. 实现自定义窗口:在自定义的窗口脚本中,我们可以通过OnGUI函数来实现GUI的绘制和交互逻辑。在这里,我们可以添加自定义的按钮、文本框、滑动条等UI元素,并通过相应的回调函数来处理用户的输入和操作。 3. 使用 SerializedObject 和 SerializedProperty:SerializedObject 和 SerializedProperty 是Unity中的序列化类,通过使用它们可以方便地访问和修改Unity对象的属性。我们可以使用这些类来实现自定义窗口中的属性编辑功能。 4. 添加自定义菜单项和工具栏按钮:通过扩展Unity的菜单和工具栏,我们可以为自定义窗口添加快捷方式。我们可以使用菜单项和工具栏按钮的回调函数来打开我们定义的自定义窗口。 5. 实现其他功能:除了基本的UI绘制和属性编辑外,我们还可以通过Unity的API来实现其他更复杂的功能,如自定义Inspector面板、自定义资源管理等。 Unity编辑器拓展是一个很有用的功能,它可以帮助我们提高开发效率,定制开发流程和工作流程。通过学习和使用Unity编辑器拓展的技术,我们可以更好地适应项目的需求,并优化我们的开发过程。希望以上内容对您有帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值