ShowIf 어트리뷰트는 오딘 인스펙터에 있는 기능이긴 합니다.
ShowIf 어트리뷰트를 사용하면 특정 컴포넌트의 조건에 따라 특정 필드를 보이게 할지 말 지를 컨트롤 할 수 있습니다.
저는 ShowIf 어트리뷰트를 응용해서 ShowIfComponent 어트리뷰트를 만들어보았습니다.
ShowIfComponent 어트리뷰트를 사용하면 특정 컴포넌트를 가지고 있을 때에만 해당 필드가 보여지게 할 수 있습니다.
ShowIfComponent Attribute 코드
Custom Attribute 제작 방법은 아래 포스팅을 참고해주세요.
using UnityEngine;
public class ShowIfComponentAttribute : PropertyAttribute
{
public string ComponentName { get; private set; }
public ShowIfComponentAttribute(string componentName)
{
ComponentName = componentName;
}
}
#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
[CustomPropertyDrawer(typeof(ShowIfComponentAttribute))]
public class ShowIfDrawer : PropertyDrawer
{
private readonly Dictionary<string, Type> componentTypeCache = new ();
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
if (ShouldShow(property))
{
EditorGUI.PropertyField(position, property, label, true);
}
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return ShouldShow(property) ? EditorGUI.GetPropertyHeight(property, label, true) : 0f;
}
private bool ShouldShow(SerializedProperty property)
{
ShowIfComponentAttribute showIfComponent = (ShowIfComponentAttribute)attribute;
Component targetComponent = property.serializedObject.targetObject as Component;
Type componentType = GetComponentType(showIfComponent.ComponentName);
return componentType != null &&
(targetComponent?.GetComponent(componentType) != null ||
targetComponent?.GetComponentInChildren(componentType) != null);
}
private Type GetComponentType(string componentName)
{
if (componentTypeCache.TryGetValue(componentName, out Type cachedType))
{
return cachedType;
}
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var componentType = assembly.GetTypes().FirstOrDefault(t => t.Name == componentName);
if (componentType != null)
{
componentTypeCache[componentName] = componentType;
return componentType;
}
}
return null;
}
}
#endif
ShowIfComponent 사용방법
[ShowIfComponent("InteractableUnityEventWrapper")] public bool SetOwnerOnGrab = false;
이렇게 사용하면 ~EventWrapper 컴포넌트가 null이 아닌 경우 SetOwnerOnGrab 필드가 인스펙터에 노출됩니다.