我有一个类,我想根据bool "segmentEnd“的值隐藏浮点数"isAStillFrame”。
我不能使用MonoBehaviour的原因是我需要类" VideoSegment“在VideoSegment所在的脚本中的序列化列表中。这个是可能的吗?现在,更改isAStillFrame的值不起任何作用。
类以修改
code
public class VideoSegment
{
public string segmentName;
public bool isAStillFrame;
public float segmentStart;
public float segmentEnd;
public List<VideoSegmentCue> segmentCues;
public VideoSegmentAction endAction;
}
code
编辑器文件夹中的编辑器脚本
code
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System.Reflection;
[CustomEditor(typeof(VideoSegment)), CanEditMultipleObjects]
public class SegmentedVideoPlayerEditor : Editor
{
private List<boolStruct> structList;
public void OnEnable()
{
structList = new List<boolStruct>();
SetBools();
}
private void SetBools()
{
HideIf("isAStillFrame", true, "segmentEnd");
}
private void HideIf(string boolName, bool boolValue, string fieldName)
{
boolStruct _boolStruct = new boolStruct()
{
targetBoolName = boolName,
targetBoolValue = boolValue,
targetVarName = fieldName,
};
structList.Add(_boolStruct);
}
public override void OnInspectorGUI()
{
serializedObject.Update();
var obj = serializedObject.GetIterator();
if (obj.NextVisible(true))
{
do
{
bool visible = true;
foreach (var i in structList)
{
if (i.targetVarName == obj.name)
{
FieldInfo boolName = target.GetType().GetField(i.targetBoolName);
var boolValue = boolName.GetValue(target);
if (boolValue.ToString() != i.targetBoolValue.ToString())
visible = false;
else
{
visible = true;
break;
}
}
}
if (visible)
EditorGUILayout.PropertyField(obj, true);
}
while (obj.NextVisible(false));
}
serializedObject.ApplyModifiedProperties();
}
private struct boolStruct
{
public string targetBoolName { get; set; }
public bool targetBoolValue { get; set; }
public string targetVarName { get; set; }
}
}
code
发布于 2022-10-12 07:49:42
如果您没有从MonoBehaviour
或ScriptableObject
继承(或者一般是从UnityEngine.Object
继承),那么使用自定义Editor
是错误的。
Editor
用于为某个可选择的资产类型实现一个完整的检查器。
您更愿意使用的是一个定制的PropertyDrawer
,它看起来可能类似于。
// First of all your class needs to be serializable
// otherwise it won't show up in the Inspector at all
[Serializable]
public class VideoSegment
{
public string segmentName;
public bool isAStillFrame;
public float segmentStart;
public float segmentEnd;
public List<VideoSegmentCue> segmentCues;
public VideoSegmentAction endAction;
}
然后
[CustomPropertyDrawer(typeof(VideoSegment))]
public class VideoSegmentDrawer : PropertyDrawer
{
// First you have to define how much vertical space your custom drawer should reserve
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
// I simply assume you want to fold your type so in this case
// it would be only the foldout label
if (!property.isExpanded)
{
return EditorGUIUtility.singleLineHeight;
}
// link up the properties
var segmentName = property.FindPropertyRelative("segmentName");
var isAStillFrame = property.FindPropertyRelative("isAStillFrame");
var segmentStart = property.FindPropertyRelative("segmentStart");
var segmentEnd = property.FindPropertyRelative("segmentEnd");
var segmentCues = property.FindPropertyRelative("segmentCues");
var endAction = property.FindPropertyRelative("endAction");
// assuming we later on use the default drawers for all properties
// we an also just use the default heights for them
return EditorGUIUtility.singleLineHeight
+ EditorGUI.GetPropertyHeight(segmentName)
+ EditorGUI.GetPropertyHeight(isAStillFrame)
+ EditorGUI.GetPropertyHeight(segmentStart)
// if your bool is checked we want to skip this field later
// so we also don't need the space for it
+ (isAStillFrame.boolValue ? 0 : EditorGUI.GetPropertyHeight(segmentEnd))
+ EditorGUI.GetPropertyHeight(segmentCues)
+ EditorGUI.GetPropertyHeight(endAction);
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
// Using BeginProperty / EndProperty on the parent property means that
// prefab override logic works on the entire property.
EditorGUI.BeginProperty(position, label, property);
// calculate rect for the foldout label
var labelRect = position;
labelRect.height = EditorGUIUtility.singleLineHeight;
position.y += EditorGUIUtility.singleLineHeight;
// Draw foldout label
property.isExpanded = EditorGUI.Foldout(labelRect, property.isExpanded, label);
// if expanded draw the rest
if (property.isExpanded)
{
// again link up poperties
var segmentName = property.FindPropertyRelative("segmentName");
var isAStillFrame = property.FindPropertyRelative("isAStillFrame");
var segmentStart = property.FindPropertyRelative("segmentStart");
var segmentEnd = property.FindPropertyRelative("segmentEnd");
var segmentCues = property.FindPropertyRelative("segmentCues");
var endAction = property.FindPropertyRelative("endAction");
// indentation - I was lazy to look it up so just used an arbitrary value
position.x += 5;
position.width -= 5;
// Calculate rect and draw segmentName
var segmentNameRect = position;
segmentNameRect.height = EditorGUI.GetPropertyHeight(segmentName);
position.y += segmentNameRect.height;
EditorGUI.PropertyField(segmentNameRect, segmentName);
// Calculate rect and draw isAStillFrame
var isAStillFrameRect = position;
isAStillFrameRect.height = EditorGUI.GetPropertyHeight(isAStillFrame);
position.y += isAStillFrameRect.height;
EditorGUI.PropertyField(isAStillFrameRect, isAStillFrame);
// Calculate rect and draw segmentStart
var segmentStartRect = position;
segmentStartRect.height = EditorGUI.GetPropertyHeight(segmentStart);
position.y += segmentStartRect.height;
EditorGUI.PropertyField(segmentStartRect, segmentStart);
// skip if your bool is set
if (!isAStillFrame.boolValue)
{
// Calculate rect and draw segmentEnd
var segmentEndRect = position;
segmentEndRect.height = EditorGUI.GetPropertyHeight(segmentEnd);
position.y += segmentEndRect.height;
EditorGUI.PropertyField(segmentEndRect, segmentEnd);
}
// Calculate rect and draw segmentCues
var segmentCuesRect = position;
segmentCuesRect.height = EditorGUI.GetPropertyHeight(segmentCues);
position.y += segmentCuesRect.height;
EditorGUI.PropertyField(segmentCuesRect, segmentCues);
// Calculate rect and draw endAction
var endActionRect = position;
endActionRect.height = EditorGUI.GetPropertyHeight(endAction);
position.y += endActionRect.height;
EditorGUI.PropertyField(endActionRect, endAction);
}
EditorGUI.EndProperty();
}
}
这看起来就像
注意:我没有您的VideoSegmentCue
和VideoSegmentAction
类型,所以我只是在演示中使用Vector3
;)
public class Test : MonoBehaviour
{
public VideoSegment singleSegment;
public List<VideoSegment> listOfSegments;
}
https://stackoverflow.com/questions/74037328
复制相似问题