编辑器拓展二:序列化与编辑器

本文介绍Unity3D中序列化与编辑器的概念、使用特性如Serializable、SerializeField及CustomEditor,并通过实例展示了如何在Inspector中显示和编辑序列化数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Unity3d编辑器拓展二:序列化与编辑器

  (2014-09-17 20:04:45)
  分类: Unity3d之脚本编程

原创文章如需转载请注明:转载自风宇冲Unity3D教程学院

                                                   
                                           序列化 与编辑器

本文需要对C#的特性概念有一定了解。有关特性见另外一篇博客:Attribute特性。
[一]概念
Serialize:序列化,使绑定于游戏对象上的脚本中的可序列化数据可以保存,以及在编辑器中编辑。

Serializable data:可序列化数据,所有如整形字符串枚举等基本数据都是可序列化数据。类和struct需要使用Serializable声明序列化。

[二]相关特性
Serializable:
声明class或者struct为序列化数据。它在JS里是隐式实现的,但是在C#需要自己实现。
例如
[System.Serializable]
public class Item
{
public string name;
public int num;
}

SerializeField:
所有public的可序列化数据都是自动序列化的。而Private的则需要在变量前附加SerializeField特性来序列化。例如。
[SerializeField]
private float myScale;

CustomEditor:
某类的自定义Inspector显示文件。例如
[CustomEditor(typeof(类名))]
public class 任意名: Editor {
void OnInspectorGUI()
{
}
}
CanEditMultipleObjects:
可编辑多个物体,附着在类前。一般和CustomEditor一同使用。

[三]序列化与编辑器拓展
在Unity中序列化的变量类等都可以通过下述方法,快速实现在编辑器中的显示与编辑。

void OnInspectorGUI()
{
//得到其中的序列化类person
SerializedProperty s_person = serializedObject.FindProperty("person");
//通过PropertyField在编辑器中显示
EditorGUILayout.PropertyField(s_person);
//保存变化后的值
serializedObject.ApplyModifiedProperties();
}

[四]实例
实例1:
【风宇冲】Unity3d编辑器拓展二:序列化与编辑器

MyClass.cs
  1. using UnityEngine;
  2. using System.Collections;

  3. [System.Serializable]
  4. public class Person
  5. {
  6. public string name;
  7. public int age;
  8. }

  9. public class MyClass : MonoBehaviour {
  10. public Person[] person;
  11. [SerializeField]
  12. private float myScale;
  13. }
MyClassInspector.cs
  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEditor;

  4. [CustomEditor(typeof(MyClass))]
  5. public class MyClassInspector : Editor {
  6. void OnInspectorGUI()
  7. {
  8. SerializedProperty s_person = serializedObject.FindProperty("person");
  9. EditorGUILayout.PropertyField(s_person);

  10. SerializedProperty s_myScale = serializedObject.FindProperty("myScale");
  11. EditorGUILayout.PropertyField(s_myScale);

  12. serializedObject.ApplyModifiedProperties();
  13. }
  14. }
可以试试看,
MyClass.cs中的第4行去掉,那么Person将不能在Inspector中编辑。
MyClass.cs中的第13行去掉,那么 myScale 将不能在Inspector中编辑。

实例2: 位移旋转缩放的重置功能
NGUI有在Inspector中 重置位移旋转缩放的功能。下面是一个仿写的简化版。

【风宇冲】Unity3d编辑器拓展二:序列化与编辑器

TransformInspector.cs
  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEditor;

  4. [CanEditMultipleObjects]
  5. [CustomEditor(typeof(Transform))]
  6. public class TransformInspector : Editor {
  7. SerializedProperty mPos;
  8. SerializedProperty mScale;
  9. public override void OnInspectorGUI()
  10. {
  11. EditorGUIUtility.labelWidth = 15f;
  12. mPos = serializedObject.FindProperty("m_LocalPosition");
  13. mScale = serializedObject.FindProperty("m_LocalScale");

  14. DrawPosition();
  15. DrawRotation();
  16. DrawScale();

  17. serializedObject.ApplyModifiedProperties();
  18. }

  19. void DrawPosition ()
  20. {
  21. GUILayout.BeginHorizontal();
  22. {
  23. bool reset = GUILayout.Button("P", GUILayout.Width(20f));
  24. EditorGUILayout.LabelField("Position",GUILayout.Width(50f));
  25. EditorGUILayout.PropertyField(mPos.FindPropertyRelative("x"));
  26. EditorGUILayout.PropertyField(mPos.FindPropertyRelative("y"));
  27. EditorGUILayout.PropertyField(mPos.FindPropertyRelative("z"));
  28. if (reset) mPos.vector3Value = Vector3.zero;
  29. }
  30. GUILayout.EndHorizontal();
  31. }

  32. void DrawScale ()
  33. {
  34. GUILayout.BeginHorizontal();
  35. {
  36. bool reset = GUILayout.Button("P", GUILayout.Width(20f));
  37. EditorGUILayout.LabelField("Scale",GUILayout.Width(50f));
  38. EditorGUILayout.PropertyField(mScale.FindPropertyRelative("x"));
  39. EditorGUILayout.PropertyField(mScale.FindPropertyRelative("y"));
  40. EditorGUILayout.PropertyField(mScale.FindPropertyRelative("z"));
  41. if (reset) mScale.vector3Value = Vector3.one;
  42. }
  43. GUILayout.EndHorizontal();
  44. }

  45. void DrawRotation ()
  46. {
  47. GUILayout.BeginHorizontal();
  48. {
  49. bool reset = GUILayout.Button("P", GUILayout.Width(20f));
  50. EditorGUILayout.LabelField("Rotation",GUILayout.Width(50f));
  51. Vector3 ls = (serializedObject.targetObject as Transform).localEulerAngles;
  52. FloatField("X",ref ls.x);
  53. FloatField("Y",ref ls.y);
  54. FloatField("Z",ref ls.z);
  55. if (reset)
  56. (serializedObject.targetObject as Transform).localEulerAngles = Vector3.zero;
  57. else
  58. (serializedObject.targetObject as Transform).localEulerAngles = ls;
  59. }
  60. GUILayout.EndHorizontal();
  61. }

  62. void FloatField(string name,ref float f)
  63. {
  64. f = EditorGUILayout.FloatField(name,f);
  65. }
  66. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值