版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33994566/article/details/84023320
没有系统性的研究unity编译器的扩展开发,所以就是遇到什么需求就去研究什么需求。之前写过一两次,后来没怎么用就忘记了。这次开发项目又遇到同样需求,我百度了半天好容易找到答案。心想这次还是记录下来,下次可以直接回顾掌握了。
一。最近在做仿真教学的内容。涉及到步骤操作检测。比如我们不打开总电源开关,我们无法打开电灯电视机电风扇。所以我们要在对每一个可交互对象操作之前都要进行判断是否满足可操作的条件。我们会在被操作对象上挂上一个我们自写的一个条件限制类,比如LimitSetting,代码如下:
public class LimitSetting : MonoBehaviour
{
public LimitList limits;
public bool CheckLimits()
{
//foreach(LimitMembers limit in limits.members)
//{
// if(limit的条件不符合) return false;
//}
return true;
}
}
[Serializable]
public class LimitList
{
public List<LimitMembers> members = new List<LimitMembers>();
}
[Serializable]
public class LimitMembers
{
public StepContrl stepContrl;
public int RightState;
}
当我们将此脚本挂在操作物体上时,Inspector面板如下:
我们需要几个条件就可以往里添加几个。但是我们可能会觉得这个界面不够直观化,想要做成Button的那种可以点击+添加的那种。如下:
这时候就需要我们扩展Inspector面板了。代码如下:记住编辑完代码要放在Editor文件夹下才可以在编译器模式下运行。
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEditorInternal;
[CustomEditor(typeof(LimitSetting))]
public class LimitSettingEditor : Editor
{
// Use this for initialization
private ReorderableList m_LimitList;
private void OnEnable()
{
m_LimitList = new ReorderableList(serializedObject,
serializedObject.FindProperty("limits").FindPropertyRelative("members"),
true, true, true, true);
m_LimitList.drawElementCallback += DrawNameElement;
m_LimitList.drawHeaderCallback = (Rect rect) =>
{
GUI.Label(rect, "添加执行条件");
};
}
private void DrawNameElement(Rect rect, int index, bool selected, bool focused)
{
SerializedProperty element = m_LimitList.serializedProperty.GetArrayElementAtIndex(index);
rect.y += 2;
rect.height = EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(new Rect(rect.x, rect.y, 200, EditorGUIUtility.singleLineHeight), element.FindPropertyRelative("stepContrl"), GUIContent.none);
EditorGUI.PropertyField(new Rect(rect.x + 200, rect.y, 100, EditorGUIUtility.singleLineHeight), element.FindPropertyRelative("RightState"), GUIContent.none);
}
public override void OnInspectorGUI()
{
serializedObject.Update();
m_LimitList.DoLayoutList();
serializedObject.ApplyModifiedProperties();
}
}
其实这个功能的用处不是很大,也不是必须。如果时间充裕可以自己编辑下,为了项目的美观化,直观化。
二。当我们在面板上添加字段值的时候,我们发现一些Object上根本不需要添加一些对应的信息。就直接为空了。当面板对外公开的字段较多时我们就容易花了眼填错行。这时候我们就可以根据各自需求显示自己需要的字段属性。比如我们写一个Test数据类脚本,代码如下:
public class Test : MonoBehaviour
{
public bool UseProperty = false;
public float speed = 0.5f;
public string Name = "";
}
当我们在面板点击UseProperty为true时,才会显示speed和Name。当为false时,隐藏speed和Name。代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
[CustomEditor(typeof(Test)), CanEditMultipleObjects]
public class TestEditor : Editor {
static SerializedProperty UseProperty, speed, Name;
private void OnEnable()
{
UseProperty = serializedObject.FindProperty("UseProperty");
speed = serializedObject.FindProperty("speed");
Name = serializedObject.FindProperty("Name");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(UseProperty);
if (UseProperty.boolValue==true)
{
EditorGUILayout.PropertyField(speed);
EditorGUILayout.PropertyField(Name);
}
serializedObject.ApplyModifiedProperties();
}
}
同样此代码要放到Editor文件夹下才会在编辑器环境下运行。