forked from Shardstone/trail-into-darkness
changed directory structure
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Jovian.InspectorTools {
|
||||
public class InterfaceComponentAttribute : PropertyAttribute {
|
||||
public readonly Type interfaceType;
|
||||
public readonly bool allowMismatch;
|
||||
|
||||
public InterfaceComponentAttribute(Type interfaceType, bool allowMismatch = false) {
|
||||
this.interfaceType = interfaceType;
|
||||
this.allowMismatch = allowMismatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
namespace Jovian.InspectorTools.Internal {
|
||||
using UnityEditor;
|
||||
|
||||
[CustomPropertyDrawer(typeof(InterfaceComponentAttribute))]
|
||||
public class InterfaceComponentAttributeDrawer : PropertyDrawer {
|
||||
|
||||
private const float MESSAGE_HEIGHT = 40f;
|
||||
private const float FIELD_HEIGHT = 18f;
|
||||
|
||||
private enum ValueImplementation {
|
||||
Null,
|
||||
Match,
|
||||
Mismatch
|
||||
}
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
|
||||
ValueImplementation valueImplementation = GetValueInterfaceImplementation(property, ((InterfaceComponentAttribute)attribute).interfaceType);
|
||||
return base.GetPropertyHeight(property, label) + (valueImplementation != ValueImplementation.Match ? MESSAGE_HEIGHT : 0f);
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
|
||||
InterfaceComponentAttribute interfaceAttribute = (InterfaceComponentAttribute)attribute;
|
||||
Type interfaceType = interfaceAttribute.interfaceType;
|
||||
bool allowMismatch = interfaceAttribute.allowMismatch;
|
||||
UnityEngine.Object value = property.objectReferenceValue;
|
||||
if(value is GameObject gameObject) {
|
||||
value = gameObject.GetComponent(interfaceType) as Component;
|
||||
if(value != null) {
|
||||
property.objectReferenceValue = value;
|
||||
property.serializedObject.ApplyModifiedPropertiesWithoutUndo();
|
||||
}
|
||||
}
|
||||
else if(value is Transform transform) {
|
||||
value = transform.GetComponent(interfaceType) as Component;
|
||||
if(value != null) {
|
||||
property.objectReferenceValue = value;
|
||||
property.serializedObject.ApplyModifiedPropertiesWithoutUndo();
|
||||
}
|
||||
}
|
||||
|
||||
ValueImplementation valueImplementation = GetValueInterfaceImplementation(property, interfaceType);
|
||||
|
||||
string message = null;
|
||||
if(valueImplementation == ValueImplementation.Null) {
|
||||
message = $"Component must implement '{interfaceType.Name}'";
|
||||
}
|
||||
else if(valueImplementation == ValueImplementation.Mismatch) {
|
||||
message = $"Component does not implement '{interfaceType.Name}'";
|
||||
|
||||
if(allowMismatch == false) {
|
||||
property.objectReferenceValue = null;
|
||||
property.serializedObject.ApplyModifiedPropertiesWithoutUndo();
|
||||
}
|
||||
}
|
||||
|
||||
if(string.IsNullOrEmpty(message) == false) {
|
||||
Rect boxPosition = new Rect(position.x, position.y, position.width, MESSAGE_HEIGHT - 2f);
|
||||
EditorGUI.HelpBox(boxPosition, message, valueImplementation == ValueImplementation.Mismatch ? MessageType.Warning : MessageType.Info);
|
||||
}
|
||||
|
||||
Rect fieldPosition = new Rect(position.x, position.yMax - FIELD_HEIGHT, position.width, FIELD_HEIGHT);
|
||||
EditorGUI.PropertyField(fieldPosition, property, label);
|
||||
}
|
||||
|
||||
private ValueImplementation GetValueInterfaceImplementation(SerializedProperty property, Type interfaceType) {
|
||||
UnityEngine.Object value = property.objectReferenceValue;
|
||||
if(value == null) {
|
||||
return ValueImplementation.Null;
|
||||
}
|
||||
else if(interfaceType.IsAssignableFrom(property.objectReferenceValue.GetType())) {
|
||||
return ValueImplementation.Match;
|
||||
}
|
||||
return ValueImplementation.Mismatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user