Unity Timeline Interaction System Integration (#17)
- Added InteractionTimelineAction component for timeline-driven interactions - Implemented custom editor for timeline event mapping - Updated interaction event flow to support timeline actions - Enhanced character move target configuration - Improved inspector UI for interactable components - Added technical documentation for interaction system - Refactored interaction action base classes for extensibility - Fixed issues with character binding in timelines Co-authored-by: Michal Pikulski <michal@foolhardyhorizons.com> Co-authored-by: Michal Pikulski <michal.a.pikulski@gmail.com> Reviewed-on: #17
This commit is contained in:
127
Assets/Editor/InteractableEditor.cs
Normal file
127
Assets/Editor/InteractableEditor.cs
Normal file
@@ -0,0 +1,127 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Interactions
|
||||
{
|
||||
[CustomEditor(typeof(Interactable))]
|
||||
public class InteractableEditor : UnityEditor.Editor
|
||||
{
|
||||
SerializedProperty isOneTimeProp;
|
||||
SerializedProperty cooldownProp;
|
||||
SerializedProperty characterToInteractProp;
|
||||
SerializedProperty interactionStartedProp;
|
||||
SerializedProperty interactionInterruptedProp;
|
||||
SerializedProperty characterArrivedProp;
|
||||
SerializedProperty interactionCompleteProp;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
isOneTimeProp = serializedObject.FindProperty("isOneTime");
|
||||
cooldownProp = serializedObject.FindProperty("cooldown");
|
||||
characterToInteractProp = serializedObject.FindProperty("characterToInteract");
|
||||
interactionStartedProp = serializedObject.FindProperty("interactionStarted");
|
||||
interactionInterruptedProp = serializedObject.FindProperty("interactionInterrupted");
|
||||
characterArrivedProp = serializedObject.FindProperty("characterArrived");
|
||||
interactionCompleteProp = serializedObject.FindProperty("interactionComplete");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.LabelField("Interaction Settings", EditorStyles.boldLabel);
|
||||
EditorGUILayout.PropertyField(isOneTimeProp);
|
||||
EditorGUILayout.PropertyField(cooldownProp);
|
||||
EditorGUILayout.PropertyField(characterToInteractProp);
|
||||
|
||||
// Add the buttons for creating move targets
|
||||
EditorGUILayout.Space(10);
|
||||
EditorGUILayout.LabelField("Character Move Targets", EditorStyles.boldLabel);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Add Trafalgar Target"))
|
||||
{
|
||||
CreateMoveTarget(CharacterToInteract.Trafalgar);
|
||||
}
|
||||
if (GUILayout.Button("Add Pulver Target"))
|
||||
{
|
||||
CreateMoveTarget(CharacterToInteract.Pulver);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
// Add a button for creating a "Both" target
|
||||
if (GUILayout.Button("Add Both Characters Target"))
|
||||
{
|
||||
CreateMoveTarget(CharacterToInteract.Both);
|
||||
}
|
||||
|
||||
// Display character target counts
|
||||
Interactable interactable = (Interactable)target;
|
||||
CharacterMoveToTarget[] moveTargets = interactable.GetComponentsInChildren<CharacterMoveToTarget>();
|
||||
int trafalgarTargets = 0;
|
||||
int pulverTargets = 0;
|
||||
int bothTargets = 0;
|
||||
|
||||
foreach (var target in moveTargets)
|
||||
{
|
||||
if (target.characterType == CharacterToInteract.Trafalgar)
|
||||
trafalgarTargets++;
|
||||
else if (target.characterType == CharacterToInteract.Pulver)
|
||||
pulverTargets++;
|
||||
else if (target.characterType == CharacterToInteract.Both)
|
||||
bothTargets++;
|
||||
}
|
||||
|
||||
EditorGUILayout.LabelField($"Trafalgar Targets: {trafalgarTargets}, Pulver Targets: {pulverTargets}, Both Targets: {bothTargets}");
|
||||
|
||||
if (trafalgarTargets > 1 || pulverTargets > 1 || bothTargets > 1 ||
|
||||
(bothTargets > 0 && (trafalgarTargets > 0 || pulverTargets > 0)))
|
||||
{
|
||||
EditorGUILayout.HelpBox("Warning: Multiple move targets found that may conflict. Priority order: Both > Character-specific targets.", MessageType.Warning);
|
||||
}
|
||||
|
||||
EditorGUILayout.Space(10);
|
||||
EditorGUILayout.LabelField("Interaction Events", EditorStyles.boldLabel);
|
||||
EditorGUILayout.PropertyField(interactionStartedProp);
|
||||
EditorGUILayout.PropertyField(interactionInterruptedProp);
|
||||
EditorGUILayout.PropertyField(characterArrivedProp);
|
||||
EditorGUILayout.PropertyField(interactionCompleteProp);
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private void CreateMoveTarget(CharacterToInteract characterType)
|
||||
{
|
||||
Interactable interactable = (Interactable)target;
|
||||
|
||||
// Create a new GameObject
|
||||
GameObject targetObj = new GameObject($"{characterType}MoveTarget");
|
||||
|
||||
// Set parent
|
||||
targetObj.transform.SetParent(interactable.transform);
|
||||
targetObj.transform.localPosition = Vector3.zero; // Start at the same position as the interactable
|
||||
|
||||
// Add CharacterMoveToTarget component
|
||||
CharacterMoveToTarget moveTarget = targetObj.AddComponent<CharacterMoveToTarget>();
|
||||
moveTarget.characterType = characterType;
|
||||
|
||||
// Position it based on character type (offset for better visibility)
|
||||
switch (characterType)
|
||||
{
|
||||
case CharacterToInteract.Trafalgar:
|
||||
moveTarget.positionOffset = new Vector3(1.0f, 0, 0);
|
||||
break;
|
||||
case CharacterToInteract.Pulver:
|
||||
moveTarget.positionOffset = new Vector3(0, 0, 1.0f);
|
||||
break;
|
||||
case CharacterToInteract.Both:
|
||||
moveTarget.positionOffset = new Vector3(0.7f, 0, 0.7f);
|
||||
break;
|
||||
}
|
||||
|
||||
// Select the newly created object
|
||||
Selection.activeGameObject = targetObj;
|
||||
Undo.RegisterCreatedObjectUndo(targetObj, $"Create {characterType} Move Target");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user