赞
踩
1.对于ScriptableObject 的属性 自定义显示,需要使用CustomPropertyDrawer
2.实现规程
需要自定义属性的脚本:
[System.Serializable]
public class TargetElementFinder
{
public FindTargetType Type;
public string Id;
public Coordinate SelfRange;
public List<Coordinate> TileRange;//集合
}
用到的类型脚本:
public enum FindTargetType
{
Self=0,
Target=1,
Player=2,
Range=3,
Global=4,
SelfRange=5,
}
[System.Serializable]
public struct Coordinate
{
public int X;
public int Y;
}
CustomPropertyDrawer 编辑器实现:
using System;
using UnityEditor;
using UnityEngine;
[CustomPropertyDrawer(typeof(TargetElementFinder))]
public class TargetElementFinder_ParamEditor : PropertyDrawer
{
private const int HeightOneLine = 20;//定义一行的高
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
//position: 在Inspector面板的位置、大小 property: 待绘制的属性 label: 值的字段名
if (!property.isExpanded)//属性是否展开
{
EditorGUI.PropertyField(position, property, new GUIContent("TargetElementFinder"), true);//显示展开的位置和名字
return;
}
//设置关闭的位置和名字
var headPosition = new Rect(position.x, position.y, position.width, HeightOneLine);
EditorGUI.PropertyField(headPosition, property, new GUIContent("TargetElementFinder"), false);
EditorGUI.indentLevel += 2;//缩进加2
var typeProperty = property.FindPropertyRelative("Type");//找到属性名为Type的属性
var typePosition = new Rect(position.x, position.y + HeightOneLine, position.width, HeightOneLine);//定义属性显示的位置
//显示枚举类型的属性
typeProperty.enumValueIndex = EditorGUI.Popup(typePosition, "Type", typeProperty.enumValueIndex, typeProperty.enumDisplayNames);
var keyValueType = (FindTargetType) Enum.GetValues(typeof(FindTargetType)).GetValue(typeProperty.enumValueIndex);
switch (keyValueType)
{
case FindTargetType.Self:
case FindTargetType.Target:
case FindTargetType.Player://这些类型 没有参数
break;
case FindTargetType.Range:
case FindTargetType.Global://这些类型有两个参数
//显示字符串参数
var idProperty = property.FindPropertyRelative("Id");
var idPosition = new Rect(typePosition.x, typePosition.y + HeightOneLine, typePosition.width, HeightOneLine);
idProperty.stringValue = EditorGUI.TextField(idPosition, "Id", idProperty.stringValue);
//显示集合参数
var tileRangeProperty = property.FindPropertyRelative("TileRange");
var tileRangePosition = new Rect(idPosition.x, idPosition.y + HeightOneLine, idPosition.width, HeightOneLine);
EditorGUI.PropertyField(tileRangePosition, tileRangeProperty, new GUIContent("TileRange"), true);
break;
case FindTargetType.SelfRange://显示类参数
var selfRangeProperty = property.FindPropertyRelative("SelfRange");
var selfRangePosition = new Rect(typePosition.x, typePosition.y + HeightOneLine, typePosition.width, HeightOneLine);
EditorGUI.PropertyField(selfRangePosition, selfRangeProperty);
break;
default:
throw new ArgumentOutOfRangeException();
}
EditorGUI.indentLevel -= 2;//恢复缩进
}
//返回属性的高度 由UnityEditor自动调用
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
if (!property.isExpanded) return HeightOneLine;//属性没有展开 高度是一行的高度
var typeProperty = property.FindPropertyRelative("Type");
var keyValueType = (FindTargetType)Enum.GetValues(typeof(FindTargetType)).GetValue(typeProperty.enumValueIndex);
switch (keyValueType)
{
case FindTargetType.Self:
case FindTargetType.Target:
case FindTargetType.Player://属性展开了,由于没有参数,只有一个属性和变量名 高度=一行高度*2
return HeightOneLine*2;
case FindTargetType.Range:
case FindTargetType.Global:
var tileRangeProperty = property.FindPropertyRelative("TileRange");
if (tileRangeProperty.isExpanded)//展开
{
var arayCount = tileRangeProperty.arraySize;
return HeightOneLine * (5 + arayCount);//根据元素的个数设置属性高度
}
else
return HeightOneLine * 4;
case FindTargetType.SelfRange://一共3行属性的显示 高度就*3
return HeightOneLine * 3;
default:
throw new ArgumentOutOfRangeException();
}
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。