Unity3D游戏开发之Unity3D场景编辑器扩展开发

今天博主想和大家分享的是Unity3D场景编辑器的扩展开发,相关的话题我们在Unity3D游戏开发之编辑器扩展程序开发实例这篇文章中我们已经有所涉及,今天博主想特别针对场景编辑器的扩展开发来进行下深入研究。对于一个场景编辑器来说,它主要的作用是3D场景视图中实时显示、输入反馈和相关信息的更新。在Unity3D中提供了Editor、EditorWindow、GUILayout、EditorGUILayout、GUIUtility、EditorGUIUtility、Handles、Event等来完成这些工作。其中基于EditorWindow的这种扩展方式我们已经研究过了,这种扩展方式拥有自己的独立窗口使用OnGUI方法进行界面的绘制。今天我们想说的是基于Editor的这种扩展方式,这种扩展方式只能针对脚本,从脚本内容在Inspector里的显示布局到变量在Scene视图的可视化编辑,它都可以完全胜任。这里特别想说的是Handles和Event这两个类,这两个类分别提供了3D显示和输入反馈的功能,我们下面就来学习如何使用这些类来扩展Unity3D的场景编辑器。

创建一个扩展的Transform组件

Transform是Unity3D中一个基本的组件,下面我们来创建一个扩展的Transform组件,该组件可以对游戏体的坐标、旋转、缩放进行重置。首先,我们创建一个ExtendTransform的类,该类继承自Editor类:

using UnityEngine;using System.Collections;using UnityEditor;[CustomEditor(typeof(Transform),true)]public class ExtendTransform : Editor {Position属性SerializedProperty mPos;Scale属性SerializedProperty mScale;void OnEnable(){mPos = serializedObject.FindProperty(“m_LocalPosition”);mScale = serializedObject.FindProperty(“m_LocalScale”) ;}Inspector相关GUI函数(){EditorGUIUtility.labelWidth = 15;//获取最新的可序列化对象serializedObject.Update();//绘制物体的坐标、旋转和缩放DrawPosition();DrawRotate();DrawScale();//更新可序列化对象的属性serializedObject.ApplyModifiedProperties();}绘制位置(){GUILayout.BeginHorizontal();{bool Reset = GUILayout.Button(“P”, GUILayout.Width(20f));EditorGUILayout.LabelField(“Position”);EditorGUILayout.PropertyField(mPos.FindPropertyRelative(“x”));EditorGUILayout.PropertyField(mPos.FindPropertyRelative(“y”));EditorGUILayout.PropertyField(mPos.FindPropertyRelative(“z”));if(Reset) mPos.vector3Value = Vector3.zero;}GUILayout.EndHorizontal();}绘制旋转(){Vector3 eulerAngles = ((Transform)target).eulerAngles;GUILayout.BeginHorizontal();{bool Reset = GUILayout.Button(“R”, GUILayout.Width(20f));EditorGUILayout.LabelField(“Rotation”, GUILayout.Width(70f));EditorGUILayout.LabelField(“X”, GUILayout.Width(13f));float angleX=EditorGUILayout.FloatField(eulerAngles.x, GUILayout.Width(56f));EditorGUILayout.LabelField(“Y”, GUILayout.Width(13f));float angleY = EditorGUILayout.FloatField(eulerAngles.y, GUILayout.Width(56f));EditorGUILayout.LabelField(“Z”, GUILayout.Width(13f));float angleZ = EditorGUILayout.FloatField(eulerAngles.z, GUILayout.Width(56f));((Transform)target).eulerAngles = new Vector3(angleX, angleY, angleZ);if(Reset){eulerAngles = Vector3.zero;((Transform)target).eulerAngles = Vector3.zero;}}GUILayout.EndHorizontal();}绘制缩放(){GUILayout.BeginHorizontal();{bool Reset = GUILayout.Button(“S”, GUILayout.Width(20f));EditorGUILayout.LabelField(“Scale”);EditorGUILayout.PropertyField(mScale.FindPropertyRelative(“x”));EditorGUILayout.PropertyField(mScale.FindPropertyRelative(“y”));EditorGUILayout.PropertyField(mScale.FindPropertyRelative(“z”));if (Reset) mScale.vector3Value = Vector3.one;}GUILayout.EndHorizontal();}}

首先我们注意到ExtendTransform继承自Editor,这是我们开发这类编辑器扩展的第一个前提。其次我们注意到在该类的声明位置有这样一个标记:

[CustomEditor(typeof(Transform),true)]

该标记表明我们这个编辑器扩展是针对Transform组件进行扩展的,即当物体存在Tranform组件时会在编辑器中响应这个编辑器扩展程序。我们在这个编辑器扩展程序中都做了哪些事情呢?第一,我们实现了OnEnable()方法,该方法相当于一个初始化的方法;第二,我们重写了OnOnInspectorGUI()方法,该方法将覆盖默认的Inspector窗口外观。

好了,现在我们点击场景中默认的相机MainCamera可以发现默认的Transform会变成具有重置功能的扩展型Transform。下面我们来介绍这段程序中较为重要的核心内容:

Unity3D中的可序列化对象

通常我们所说的序列化是指将一个对象的实例转化为字符串的过程,而在Unity3D中可序列化对象更像是一种智能对象,它可以将脚本中的属性显示在Inspector窗口中,当场景发生变化时这些属性值将自动被更新。例如我们可以定义这样一个简单的脚本:

定义一个可序列化类/// </summary>[System.Serializable]public class ExampleClass {[SerializeField]public int ID;[SerializeField]public string Name;[SerializeField]public Vector3[] Points;private bool editable = false;}定义一个简单的脚本ExampleScript : MonoBehaviour {public ExampleClass Example;}如果你不出去走走,你就会以为这就是世界。

Unity3D游戏开发之Unity3D场景编辑器扩展开发

相关文章:

你感兴趣的文章:

标签云: