mirror of
https://github.com/unity-atoms/unity-atoms.git
synced 2025-01-22 08:08:51 -05:00
implements "Auto DragAndDrop UsageTypeDetection" for reference fields based on PR from @toasterhead-master
- contains only changes regarding to the feature itself without any of the refactoring - reduces the amount of boilerplate classes Closes: #441 Co-authored-by: ToasterHead<toasterhead-master>
This commit is contained in:
parent
37ead24dbb
commit
2ddefb7f4a
@ -7,7 +7,7 @@ namespace UnityAtoms.BaseAtoms.Editor
|
|||||||
/// A custom property drawer for AtomCollectionReference. Makes it possible to choose between a Collection or a Collection Instancer.
|
/// A custom property drawer for AtomCollectionReference. Makes it possible to choose between a Collection or a Collection Instancer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[CustomPropertyDrawer(typeof(AtomCollectionReference), true)]
|
[CustomPropertyDrawer(typeof(AtomCollectionReference), true)]
|
||||||
public class AtomCollectionReferenceDrawer : AtomBaseReferenceDrawer
|
public class AtomCollectionReferenceDrawer : AtomBaseReferenceDrawer<AtomCollectionInstancer>
|
||||||
{
|
{
|
||||||
protected class UsageCollection : UsageData
|
protected class UsageCollection : UsageData
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@ namespace UnityAtoms.BaseAtoms.Editor
|
|||||||
/// A custom property drawer for AtomListReference. Makes it possible to choose between a List or a List Instancer.
|
/// A custom property drawer for AtomListReference. Makes it possible to choose between a List or a List Instancer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[CustomPropertyDrawer(typeof(AtomListReference), true)]
|
[CustomPropertyDrawer(typeof(AtomListReference), true)]
|
||||||
public class AtomListReferenceDrawer : AtomBaseReferenceDrawer
|
public class AtomListReferenceDrawer : AtomBaseReferenceDrawer<AtomListInstancer>
|
||||||
{
|
{
|
||||||
protected class UsageList : UsageData
|
protected class UsageList : UsageData
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@ namespace UnityAtoms.BaseAtoms.Editor
|
|||||||
/// A custom property drawer for AtomBaseVariable BaseEventReferences. Makes it possible to choose between an Event, Event Instancer, Collection Added, Collection Removed, List Added, List Removed, Collection Instancer Added, Collection Instancer Removed, List Instancer Added or List Instancer Removed.
|
/// A custom property drawer for AtomBaseVariable BaseEventReferences. Makes it possible to choose between an Event, Event Instancer, Collection Added, Collection Removed, List Added, List Removed, Collection Instancer Added, Collection Instancer Removed, List Instancer Added or List Instancer Removed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[CustomPropertyDrawer(typeof(AtomBaseVariableBaseEventReference), true)]
|
[CustomPropertyDrawer(typeof(AtomBaseVariableBaseEventReference), true)]
|
||||||
public class AtomBaseVariableBaseEventReferenceDrawer : AtomBaseReferenceDrawer
|
public class AtomBaseVariableBaseEventReferenceDrawer : AtomBaseReferenceDrawer<AtomBaseVariableEventInstancer>
|
||||||
{
|
{
|
||||||
protected class UsageEvent : UsageData
|
protected class UsageEvent : UsageData
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@ namespace UnityAtoms.BaseAtoms.Editor
|
|||||||
/// A custom property drawer for Void BaseEventReferences. Makes it possible to choose between an Event, Event Instancer, Collection Cleared, List Cleared, Collection Instancer Cleared or List Instancer Cleared.
|
/// A custom property drawer for Void BaseEventReferences. Makes it possible to choose between an Event, Event Instancer, Collection Cleared, List Cleared, Collection Instancer Cleared or List Instancer Cleared.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[CustomPropertyDrawer(typeof(VoidBaseEventReference), true)]
|
[CustomPropertyDrawer(typeof(VoidBaseEventReference), true)]
|
||||||
public class VoidBaseEventReferenceDrawer : AtomBaseReferenceDrawer
|
public class VoidBaseEventReferenceDrawer : AtomBaseReferenceDrawer<VoidEventInstancer>
|
||||||
{
|
{
|
||||||
protected class UsageEvent : UsageData
|
protected class UsageEvent : UsageData
|
||||||
{
|
{
|
||||||
|
@ -8,7 +8,8 @@ namespace UnityAtoms.Editor
|
|||||||
/// A custom property drawer for References (Events and regular). Makes it possible to reference a resources (Variable or Event) through multiple options.
|
/// A custom property drawer for References (Events and regular). Makes it possible to reference a resources (Variable or Event) through multiple options.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
public abstract class AtomBaseReferenceDrawer : PropertyDrawer
|
public abstract class AtomBaseReferenceDrawer<TInstancerType> : PropertyDrawer
|
||||||
|
where TInstancerType : MonoBehaviour
|
||||||
{
|
{
|
||||||
protected abstract class UsageData
|
protected abstract class UsageData
|
||||||
{
|
{
|
||||||
@ -16,6 +17,7 @@ namespace UnityAtoms.Editor
|
|||||||
public abstract string PropertyName { get; }
|
public abstract string PropertyName { get; }
|
||||||
public abstract string DisplayName { get; }
|
public abstract string DisplayName { get; }
|
||||||
}
|
}
|
||||||
|
const string USAGE_PROPERTY_NAME = "_usage";
|
||||||
|
|
||||||
protected abstract UsageData[] GetUsages(SerializedProperty prop = null);
|
protected abstract UsageData[] GetUsages(SerializedProperty prop = null);
|
||||||
|
|
||||||
@ -24,7 +26,7 @@ namespace UnityAtoms.Editor
|
|||||||
|
|
||||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||||
{
|
{
|
||||||
var usageIntVal = property.FindPropertyRelative("_usage").intValue;
|
var usageIntVal = property.FindPropertyRelative(USAGE_PROPERTY_NAME).intValue;
|
||||||
var usageData = GetUsages(property)[0];
|
var usageData = GetUsages(property)[0];
|
||||||
for (var i = 0; i < GetUsages(property).Length; ++i)
|
for (var i = 0; i < GetUsages(property).Length; ++i)
|
||||||
{
|
{
|
||||||
@ -67,8 +69,9 @@ namespace UnityAtoms.Editor
|
|||||||
int indent = EditorGUI.indentLevel;
|
int indent = EditorGUI.indentLevel;
|
||||||
EditorGUI.indentLevel = 0;
|
EditorGUI.indentLevel = 0;
|
||||||
|
|
||||||
var currentUsage = property.FindPropertyRelative("_usage");
|
var currentUsage = property.FindPropertyRelative(USAGE_PROPERTY_NAME);
|
||||||
var newUsageValue = EditorGUI.Popup(buttonRect, currentUsage.intValue, GetPopupOptions(property), _popupStyle);
|
var newUsageValue = EditorGUI.Popup(buttonRect, currentUsage.intValue, GetPopupOptions(property), _popupStyle);
|
||||||
|
DetermineDragAndDropFieldReferenceType(position, property, ref newUsageValue);
|
||||||
currentUsage.intValue = newUsageValue;
|
currentUsage.intValue = newUsageValue;
|
||||||
|
|
||||||
var usageTypePropertyName = GetUsages(property)[newUsageValue].PropertyName;
|
var usageTypePropertyName = GetUsages(property)[newUsageValue].PropertyName;
|
||||||
@ -100,5 +103,63 @@ namespace UnityAtoms.Editor
|
|||||||
EditorGUI.indentLevel = indent;
|
EditorGUI.indentLevel = indent;
|
||||||
EditorGUI.EndProperty();
|
EditorGUI.EndProperty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Auto DragAndDrop UsageTypeDetection
|
||||||
|
private void DetermineDragAndDropFieldReferenceType(in Rect position, SerializedProperty property,
|
||||||
|
ref int newUsageValue)
|
||||||
|
{
|
||||||
|
EventType mouseEventType = Event.current.type;
|
||||||
|
|
||||||
|
if (mouseEventType != EventType.DragUpdated && mouseEventType != EventType.DragPerform)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!IsMouseHoveringOverProperty(position))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var draggedObjects = DragAndDrop.objectReferences;
|
||||||
|
|
||||||
|
if (draggedObjects.Length < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Object draggedObject = draggedObjects[0];
|
||||||
|
|
||||||
|
if (draggedObject is GameObject gameObject)
|
||||||
|
draggedObject = gameObject.GetComponent<TInstancerType>();
|
||||||
|
|
||||||
|
UpdateConfigurationOption(property, draggedObject, ref newUsageValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateConfigurationOption(SerializedProperty property, Object draggedObject, ref int newUsageValue)
|
||||||
|
{
|
||||||
|
if (!draggedObject)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var usages = GetUsages(property);
|
||||||
|
|
||||||
|
for (int index = 0; index < usages.Length; index++)
|
||||||
|
{
|
||||||
|
var usage = usages[index];
|
||||||
|
SerializedProperty fieldProperty = property.FindPropertyRelative(usage.PropertyName);
|
||||||
|
string draggedObjectType = draggedObject.GetType().Name;
|
||||||
|
string fieldPropertyType = fieldProperty.type.Replace("PPtr<$", "").Replace(">", "");
|
||||||
|
|
||||||
|
if (draggedObjectType == fieldPropertyType)
|
||||||
|
{
|
||||||
|
newUsageValue = index;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsMouseHoveringOverProperty(Rect rectPosition)
|
||||||
|
{
|
||||||
|
const int HEIGHT_OFFSET_TO_AVOID_OVERLAP = 1;
|
||||||
|
Rect controlRect = rectPosition;
|
||||||
|
controlRect.height -= HEIGHT_OFFSET_TO_AVOID_OVERLAP;
|
||||||
|
|
||||||
|
return controlRect.Contains(Event.current.mousePosition);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ namespace UnityAtoms.Editor
|
|||||||
/// A custom property drawer for Event References. Makes it possible to choose between an Event, Event Instancer, Variable or a Variable Instancer.
|
/// A custom property drawer for Event References. Makes it possible to choose between an Event, Event Instancer, Variable or a Variable Instancer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[CustomPropertyDrawer(typeof(AtomBaseEventReference), true)]
|
[CustomPropertyDrawer(typeof(AtomBaseEventReference), true)]
|
||||||
public class AtomEventReferenceDrawer : AtomBaseReferenceDrawer
|
public class AtomEventReferenceDrawer : AtomBaseReferenceDrawer<AtomEventInstancer>
|
||||||
{
|
{
|
||||||
protected class UsageEvent : UsageData
|
protected class UsageEvent : UsageData
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@ namespace UnityAtoms.Editor
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
[CustomPropertyDrawer(typeof(AtomBaseReference), true)]
|
[CustomPropertyDrawer(typeof(AtomBaseReference), true)]
|
||||||
public class AtomReferenceDrawer : AtomBaseReferenceDrawer
|
public class AtomReferenceDrawer : AtomBaseReferenceDrawer<AtomBaseVariableInstancer>
|
||||||
{
|
{
|
||||||
protected class UsageValue : UsageData
|
protected class UsageValue : UsageData
|
||||||
{
|
{
|
||||||
|
@ -5,6 +5,11 @@ using UnityEngine.Assertions;
|
|||||||
namespace UnityAtoms
|
namespace UnityAtoms
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public abstract class AtomEventInstancer : MonoBehaviour
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An Event Instancer is a MonoBehaviour that takes an Event as a base and creates an in memory copy of it on OnEnable.
|
/// An Event Instancer is a MonoBehaviour that takes an Event as a base and creates an in memory copy of it on OnEnable.
|
||||||
/// This is handy when you want to use Events for prefabs that are instantiated at runtime.
|
/// This is handy when you want to use Events for prefabs that are instantiated at runtime.
|
||||||
@ -13,7 +18,7 @@ namespace UnityAtoms
|
|||||||
/// <typeparam name="E">Event of type T.</typeparam>
|
/// <typeparam name="E">Event of type T.</typeparam>
|
||||||
[EditorIcon("atom-icon-sign-blue")]
|
[EditorIcon("atom-icon-sign-blue")]
|
||||||
[DefaultExecutionOrder(Runtime.ExecutionOrder.VARIABLE_INSTANCER)]
|
[DefaultExecutionOrder(Runtime.ExecutionOrder.VARIABLE_INSTANCER)]
|
||||||
public abstract class AtomEventInstancer<T, E> : MonoBehaviour, IGetEvent, ISetEvent
|
public abstract class AtomEventInstancer<T, E> : AtomEventInstancer, IGetEvent, ISetEvent
|
||||||
where E : AtomEvent<T>
|
where E : AtomEvent<T>
|
||||||
{
|
{
|
||||||
public T InspectorRaiseValue { get => _inspectorRaiseValue; }
|
public T InspectorRaiseValue { get => _inspectorRaiseValue; }
|
||||||
|
@ -4,6 +4,11 @@ using UnityEngine.Assertions;
|
|||||||
|
|
||||||
namespace UnityAtoms
|
namespace UnityAtoms
|
||||||
{
|
{
|
||||||
|
public abstract class AtomBaseVariableInstancer : MonoBehaviour
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A Variable Instancer is a MonoBehaviour that takes a variable as a base and creates an in memory copy of it OnEnable.
|
/// A Variable Instancer is a MonoBehaviour that takes a variable as a base and creates an in memory copy of it OnEnable.
|
||||||
/// This is handy when you want to use atoms for prefabs that are instantiated at runtime. Use together with AtomCollection to
|
/// This is handy when you want to use atoms for prefabs that are instantiated at runtime. Use together with AtomCollection to
|
||||||
@ -17,7 +22,7 @@ namespace UnityAtoms
|
|||||||
/// <typeparam name="F">Function of type T => T</typeparam>
|
/// <typeparam name="F">Function of type T => T</typeparam>
|
||||||
[EditorIcon("atom-icon-hotpink")]
|
[EditorIcon("atom-icon-hotpink")]
|
||||||
[DefaultExecutionOrder(Runtime.ExecutionOrder.VARIABLE_INSTANCER)]
|
[DefaultExecutionOrder(Runtime.ExecutionOrder.VARIABLE_INSTANCER)]
|
||||||
public abstract class AtomBaseVariableInstancer<T, V> : MonoBehaviour, IVariable<V>
|
public abstract class AtomBaseVariableInstancer<T, V> : AtomBaseVariableInstancer, IVariable<V>
|
||||||
where V : AtomBaseVariable<T>
|
where V : AtomBaseVariable<T>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -25,6 +30,22 @@ namespace UnityAtoms
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public V Variable { get => _inMemoryCopy; }
|
public V Variable { get => _inMemoryCopy; }
|
||||||
|
|
||||||
|
public void SetSource(V variable)
|
||||||
|
{
|
||||||
|
_base = variable;
|
||||||
|
if (Application.isPlaying)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Setting the underlying variable of an instancers at runtime can result in hard to find issues. be careful.");
|
||||||
|
if (_inMemoryCopy != null)
|
||||||
|
{
|
||||||
|
Destroy(_inMemoryCopy);
|
||||||
|
_inMemoryCopy = null;
|
||||||
|
}
|
||||||
|
OnEnable();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Getter for retrieving the value of the in memory runtime variable.
|
/// Getter for retrieving the value of the in memory runtime variable.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -7,7 +7,7 @@ namespace UnityAtoms.FSM.Editor
|
|||||||
/// A custom property drawer for FiniteStateMachineReference. Makes it possible to choose between a FSM or a FSM Instancer.
|
/// A custom property drawer for FiniteStateMachineReference. Makes it possible to choose between a FSM or a FSM Instancer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[CustomPropertyDrawer(typeof(FiniteStateMachineReference), true)]
|
[CustomPropertyDrawer(typeof(FiniteStateMachineReference), true)]
|
||||||
public class FiniteStateMachineReferenceDrawer : AtomBaseReferenceDrawer
|
public class FiniteStateMachineReferenceDrawer : AtomBaseReferenceDrawer<FiniteStateMachineInstancer>
|
||||||
{
|
{
|
||||||
protected class UsageFSM : UsageData
|
protected class UsageFSM : UsageData
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user