原文地址:https://catlikecoding.com/unity/tutorials/object-management/multiple-scenes/
阅读国外Coder教程时的笔记,Object Management篇(一)
阅读国外Coder教程时的笔记,Object Management篇(二)
阅读国外Coder教程时的笔记,Object Management篇(三)
阅读国外Coder教程时的笔记,Object Management篇(四)
阅读国外Coder教程时的笔记,Object Management篇(五)
阅读国外Coder教程时的笔记,Object Management篇(六)
1.如何在Inspector面板上绘制UI
下图是我们在Inspector面板上看到的常规界面,枚举+结构体嵌套
代码:
[System.Serializable]
public struct SpawnConfiguration {
public enum MovementDirection
{
Forward,
Upward,
Outward,
Random
}
public MovementDirection movementDirection;
public CreatingFloatRange speed;
public CreatingFloatRange angularSpeed;
public CreatingFloatRange scale;
public ColorRangeHSV color;
}
//嵌套结构体
[System.Serializable]
public struct CreatingFloatRange
{
public float min, max;
public float RandomValueInRange {
get {
return Random.Range(min,max);
}
}
}
这样看上去是不是有点不太简洁?再看下图是不是就简洁多了。
以上主要通过在Editor文件夹下新建一个绘制UI的脚本实现。
代码如下,意思有点像用代码设置他们的位置关系:
using UnityEngine;
using UnityEditor;
[CustomPropertyDrawer(typeof(CreatingFloatRange))]
public class CreatingFloatRangeDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
int originalIndentLevel = EditorGUI.indentLevel;
float originalLabelWidth = EditorGUIUtility.labelWidth;
EditorGUI.BeginProperty(position,label,property) ;
position = EditorGUI.PrefixLabel(position,GUIUtility.GetControlID(FocusType.Passive),label);
position.width = position.width / 2f;
EditorGUIUtility.labelWidth = position.width / 2f;
EditorGUI.indentLevel = 1;
EditorGUI.PropertyField(position,property.FindPropertyRelative("min"));
position.x += position.width;
EditorGUI.PropertyField(position, property.FindPropertyRelative("max"));
EditorGUI.EndProperty();
EditorGUI.indentLevel = originalIndentLevel;
EditorGUIUtility.labelWidth = originalLabelWidth;
}
}
对于最大值和最小值固定的范围,比如说色值。我们可以设置程下图所示:
原理和上面的相同,但是稍微麻烦一点。
首先把常规的Range类替换程自定义的范围类,这个类必须继承PropertyAttribute类。比如:
using UnityEngine;
public class FloatRangeSliderAttribute : PropertyAttribute
{
public float Min { get; private set; }
public float Max { get; private set; }
public FloatRangeSliderAttribute(float min, float max) {
if (max < min) {
max = min;
}
Min = min;
Max = max;
}
}
//这里可以使用自定义的范围类
[FloatRangeSlider(0f,1f)]
public CreatingFloatRange hue, saturation, value;
然后和开始一样,在Editor文件下新建一个绘制UI的脚本,具体如下:
using UnityEditor;
using UnityEngine;
[CustomPropertyDrawer(typeof(FloatRangeSliderAttribute))]
public class FloatRangeSliderDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
int originalIndentLevel = EditorGUI.indentLevel;
EditorGUI.BeginProperty(position,label,property);
position = EditorGUI.PrefixLabel(position,GUIUtility.GetControlID(FocusType.Passive),label);
EditorGUI.indentLevel = 0;
SerializedProperty minProperty = property.FindPropertyRelative("min");
SerializedProperty maxProperty = property.FindPropertyRelative("max");
float minValue = minProperty.floatValue;
float maxValue = maxProperty.floatValue;
float fieldWidth = position.width / 4f - 4f;
float sliderWidth = position.width / 2f;
position.width = fieldWidth;
minValue = EditorGUI.FloatField(position,minValue);
position.x += fieldWidth+4f;
position.width = sliderWidth;
FloatRangeSliderAttribute limit = attribute as FloatRangeSliderAttribute;
EditorGUI.MinMaxSlider(position,ref minValue,ref maxValue,limit.Min,limit.Max);
position.x += sliderWidth+4f;
position.width = fieldWidth;
maxValue = EditorGUI.FloatField(position,maxValue);
if (minValue < limit.Min)
{
minValue = limit.Min;
}
else if (minValue > limit.Max) {
minValue = limit.Max;
}
if (maxValue < minValue)
{
maxValue = minValue;
}
else if (maxValue > limit.Max) {
maxValue = limit.Max;
}
minProperty.floatValue = minValue;
maxProperty.floatValue = maxValue;
EditorGUI.EndProperty();
EditorGUI.indentLevel = originalIndentLevel;
}
}
具体详细就不介绍了,可以当成一个工具使用,只要替换FindPropertyRelative里的参数就好了。
以上,希望可以帮助到大家学习。