Hello, I’m working on my ShowIf attribute.
I’m trying to use a PropertyDrawer to hide or show an property. It works well on single variables. But when it comes to an array, it looks like I’m dealing with every single element of the array instead of the array itself.
[CustomPropertyDrawer(typeof(MyShowIfAttribute))]
public class MyShowIfAttributeDrawer : PropertyDrawer {
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {}
The parameter property
seems to refer to an element, not the array.
Here’s the definition of the attribute:
using UnityEngine;
public class MyShowIfAttribute : PropertyAttribute {
public string ConditionFieldName { get; private set; }
public bool ExpectedValue { get; private set; }
public MyShowIfAttribute(string conditionFieldName, bool expectedValue = true)
{
ConditionFieldName = conditionFieldName;
ExpectedValue = expectedValue;
}
}
This is where I use the attribute. ComboKey
is just an enum. I want to show inputKeys
only when receiveDirection
is true:
using System;
using System.Collections.Generic;
namespace ComboInput {
[Serializable]
public class Combo {
public InputType inputType;
[MyShowIf(nameof(receiveDirection))]
public ComboKey[] inputKeys;
public ComboKey inputKey;
public bool receiveDirection;
public bool needDirection;
public ActionKey action;
private int SimultaneousMask;
}
}
When I try to get the property from OnGUI
, I can only get every element.
Code of the Attribute Drawer
using System;
using UnityEngine;
using UnityEditor;
[CustomPropertyDrawer(typeof(MyShowIfAttribute))]
public class MyShowIfAttributeDrawer : PropertyDrawer {
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
MyShowIfAttribute showIf = (MyShowIfAttribute)attribute;
string path = !property.propertyPath.Contains(".")
? showIf.ConditionFieldName
: property.propertyPath.Contains("Array.data[") && property.propertyPath.EndsWith(']')
? System.IO.Path.ChangeExtension(
property.propertyPath.Substring(0,
property.propertyPath.LastIndexOf("Array.data", StringComparison.Ordinal) - 1),
showIf.ConditionFieldName)
: System.IO.Path.ChangeExtension(property.propertyPath, showIf.ConditionFieldName)
;
SerializedProperty conditionProperty = property.serializedObject.FindProperty(path);
Debug.LogWarning("Property Path: " + property.propertyPath
+ "\nYour Path: " + path
+ "\nThis property is " + (property.isArray ? "" : "not ") + "array.");
if (conditionProperty != null) {
bool shouldShow = IsConditionMet(conditionProperty, showIf.ExpectedValue);
if (shouldShow) {
EditorGUI.PropertyField(position, property, label, true);
}
}
else {
Debug.LogWarning($"Cannot find property with name {showIf.ConditionFieldName}");
}
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
MyShowIfAttribute showIf = (MyShowIfAttribute)attribute;
string path = !property.propertyPath.Contains(".")
? showIf.ConditionFieldName
: property.propertyPath.Contains("Array.data[") && property.propertyPath.EndsWith(']')
? System.IO.Path.ChangeExtension(
property.propertyPath.Substring(0,
property.propertyPath.LastIndexOf("Array.data", StringComparison.Ordinal) - 1),
showIf.ConditionFieldName)
: System.IO.Path.ChangeExtension(property.propertyPath, showIf.ConditionFieldName)
;
SerializedProperty conditionProperty = property.serializedObject.FindProperty(path);
if (conditionProperty != null && IsConditionMet(conditionProperty, showIf.ExpectedValue)) {
return EditorGUI.GetPropertyHeight(property, label, true);
}
else {
return 0f; // Hide property by setting height to 0
}
}
private bool IsConditionMet(SerializedProperty conditionProperty, object expectedValue) {
switch (conditionProperty.propertyType) {
case SerializedPropertyType.Boolean:
return conditionProperty.boolValue.Equals(expectedValue);
default:
Debug.LogWarning("Unsupported property type for ShowIf attribute.");
return true;
}
}
}
The logs from line 20 look like these:
And the inspector looks like this (
ComboList
is List<Combo>
):The whole list is expected to hide but I can only hide every single element now.
What’s the problem? Is it possible to fix this?