Unity Timeline Interaction System Integration #17

Merged
tschesky merged 4 commits from unity_timeline_on_interact into main 2025-10-07 10:57:11 +00:00
24 changed files with 3148 additions and 35 deletions
Showing only changes of commit fd611ac27f - Show all commits

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

@@ -0,0 +1,195 @@
fileFormatVersion: 2
guid: 44a64b7a80921694790236bab7765357
TextureImporter:
internalIDToNameTable:
- first:
213: -8897872742393391051
second: TennisBall_0
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 2
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: iOS
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WindowsStoreApps
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites:
- serializedVersion: 2
name: TennisBall_0
rect:
serializedVersion: 2
x: 21
y: 29
width: 219
height: 190
alignment: 0
pivot: {x: 0, y: 0}
border: {x: 0, y: 0, z: 0, w: 0}
customData:
outline: []
physicsShape: []
tessellationDetail: -1
bones: []
spriteID: 538d20d32e7648480800000000000000
internalID: -8897872742393391051
vertices: []
indices:
edges: []
weights: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable:
TennisBall_0: -8897872742393391051
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View 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");
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e2011e96b1b84886825d0509dd0a5cee
timeCreated: 1759744192

View File

@@ -0,0 +1,184 @@
using UnityEngine;
using UnityEditor;
using UnityEditor.Playables;
using UnityEngine.Playables;
namespace Interactions
{
[CustomEditor(typeof(InteractionTimelineAction))]
public class InteractionTimelineActionEditor : UnityEditor.Editor
{
private SerializedProperty respondToEventsProp;
private SerializedProperty pauseInteractionFlowProp;
private SerializedProperty playableDirectorProp;
private SerializedProperty timelineMappingsProp;
private void OnEnable()
{
respondToEventsProp = serializedObject.FindProperty("respondToEvents");
pauseInteractionFlowProp = serializedObject.FindProperty("pauseInteractionFlow");
playableDirectorProp = serializedObject.FindProperty("playableDirector");
timelineMappingsProp = serializedObject.FindProperty("timelineMappings");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
// Basic properties from the base class
EditorGUILayout.LabelField("Basic Settings", EditorStyles.boldLabel);
// Show the pause interaction flow property
EditorGUILayout.PropertyField(pauseInteractionFlowProp, new GUIContent("Pause Interaction Flow",
"If true, the interaction will wait for the timeline to complete before proceeding"));
// Show the respondToEvents list
EditorGUILayout.PropertyField(respondToEventsProp, new GUIContent("Respond To Events",
"Select which interaction events this timeline action should respond to"), true);
// Show the playable director reference
EditorGUILayout.PropertyField(playableDirectorProp, new GUIContent("Playable Director",
"The director component that will play the timeline. Auto-assigned if not specified."));
// Show the timeline mappings
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("Timeline Mappings", EditorStyles.boldLabel);
if (timelineMappingsProp.arraySize == 0)
{
EditorGUILayout.HelpBox("No timeline mappings added yet. Add one to assign timeline assets to specific interaction events.", MessageType.Info);
}
EditorGUILayout.PropertyField(timelineMappingsProp, new GUIContent("Timeline Mappings"), true);
// Add buttons for quickly adding timeline mappings for common events
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("Quick Add Mappings", EditorStyles.boldLabel);
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Add Player Arrival"))
{
AddTimelineMapping(InteractionEventType.PlayerArrived);
}
if (GUILayout.Button("Add Interacting Character"))
{
AddTimelineMapping(InteractionEventType.InteractingCharacterArrived);
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Add Interaction Started"))
{
AddTimelineMapping(InteractionEventType.InteractionStarted);
}
if (GUILayout.Button("Add Interaction Complete"))
{
AddTimelineMapping(InteractionEventType.InteractionComplete);
}
EditorGUILayout.EndHorizontal();
// Check for configuration issues
InteractionTimelineAction timelineAction = (InteractionTimelineAction)target;
ValidateConfiguration(timelineAction);
serializedObject.ApplyModifiedProperties();
}
private void AddTimelineMapping(InteractionEventType eventType)
{
int index = timelineMappingsProp.arraySize;
timelineMappingsProp.InsertArrayElementAtIndex(index);
SerializedProperty newElement = timelineMappingsProp.GetArrayElementAtIndex(index);
// Set default values
newElement.FindPropertyRelative("eventType").enumValueIndex = (int)eventType;
// Create a default array with one empty slot for the timeline
SerializedProperty timelinesArray = newElement.FindPropertyRelative("timelines");
timelinesArray.ClearArray();
timelinesArray.InsertArrayElementAtIndex(0);
timelinesArray.GetArrayElementAtIndex(0).objectReferenceValue = null;
// Set default binding values
newElement.FindPropertyRelative("bindPlayerCharacter").boolValue = false;
newElement.FindPropertyRelative("bindPulverCharacter").boolValue = false;
newElement.FindPropertyRelative("playerTrackName").stringValue = "Player";
newElement.FindPropertyRelative("pulverTrackName").stringValue = "Pulver";
newElement.FindPropertyRelative("timeoutSeconds").floatValue = 30f;
newElement.FindPropertyRelative("loopLast").boolValue = false;
newElement.FindPropertyRelative("loopAll").boolValue = false;
// Also add the event to the respondToEvents list if it's not already there
bool found = false;
for (int i = 0; i < respondToEventsProp.arraySize; i++)
{
if (respondToEventsProp.GetArrayElementAtIndex(i).enumValueIndex == (int)eventType)
{
found = true;
break;
}
}
if (!found)
{
int responseIndex = respondToEventsProp.arraySize;
respondToEventsProp.InsertArrayElementAtIndex(responseIndex);
respondToEventsProp.GetArrayElementAtIndex(responseIndex).enumValueIndex = (int)eventType;
}
}
private void ValidateConfiguration(InteractionTimelineAction timelineAction)
{
// Check if we have a PlayableDirector component
PlayableDirector director = timelineAction.GetComponent<PlayableDirector>();
if (director == null)
{
EditorGUILayout.HelpBox("This GameObject is missing a PlayableDirector component, which is required for timeline playback.", MessageType.Error);
}
// Check if we have mappings but no events to respond to
if (timelineMappingsProp.arraySize > 0 && respondToEventsProp.arraySize == 0)
{
EditorGUILayout.HelpBox("You have timeline mappings but no events to respond to. Add events to the 'Respond To Events' list.", MessageType.Warning);
}
// Check if we have events to respond to but no mappings for them
bool hasUnmappedEvents = false;
for (int i = 0; i < respondToEventsProp.arraySize; i++)
{
InteractionEventType eventType = (InteractionEventType)respondToEventsProp.GetArrayElementAtIndex(i).enumValueIndex;
bool found = false;
for (int j = 0; j < timelineMappingsProp.arraySize; j++)
{
SerializedProperty mappingProp = timelineMappingsProp.GetArrayElementAtIndex(j);
InteractionEventType mappingEventType = (InteractionEventType)mappingProp.FindPropertyRelative("eventType").enumValueIndex;
if (mappingEventType == eventType)
{
found = true;
// Check if the mapping has timelines assigned
SerializedProperty timelinesArray = mappingProp.FindPropertyRelative("timelines");
if (timelinesArray.arraySize == 0 || timelinesArray.GetArrayElementAtIndex(0).objectReferenceValue == null)
{
EditorGUILayout.HelpBox($"The mapping for {eventType} has no timeline assets assigned.", MessageType.Warning);
}
break;
}
}
if (!found)
{
hasUnmappedEvents = true;
break;
}
}
if (hasUnmappedEvents)
{
EditorGUILayout.HelpBox("Some events in 'Respond To Events' have no timeline mapping.", MessageType.Warning);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6ab56ee48f1445529a62d30c1985f059
timeCreated: 1759746824

View File

@@ -0,0 +1,48 @@
using UnityEngine;
using UnityEditor;
using Interactions;
using System;
[CustomPropertyDrawer(typeof(InteractionTimelineAction.TimelineEventMapping))]
public class TimelineEventMappingDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
// Use default property drawer, but initialize values if needed
InitializeDefaultValues(property);
EditorGUI.PropertyField(position, property, label, true);
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUI.GetPropertyHeight(property, label, true);
}
// Called when property is created to initialize default values
private void InitializeDefaultValues(SerializedProperty property)
{
// Check if this is a new/empty property that needs initialization
SerializedProperty timelinesArray = property.FindPropertyRelative("timelines");
if (timelinesArray != null && timelinesArray.arraySize == 0)
{
// This appears to be a new property, so initialize default values
// Initialize timelines array with one empty element
timelinesArray.ClearArray();
timelinesArray.InsertArrayElementAtIndex(0);
timelinesArray.GetArrayElementAtIndex(0).objectReferenceValue = null;
// Set default binding values
property.FindPropertyRelative("bindPlayerCharacter").boolValue = true;
property.FindPropertyRelative("bindPulverCharacter").boolValue = true;
property.FindPropertyRelative("playerTrackName").stringValue = "Player";
property.FindPropertyRelative("pulverTrackName").stringValue = "Pulver";
property.FindPropertyRelative("timeoutSeconds").floatValue = 30f;
property.FindPropertyRelative("loopLast").boolValue = false;
property.FindPropertyRelative("loopAll").boolValue = false;
// Make sure to apply modifications
property.serializedObject.ApplyModifiedProperties();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c5a227e33ab14a0f86bf391016c57b00
timeCreated: 1759756346

View File

@@ -0,0 +1,854 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-1185821560092742700
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d21dcc2386d650c4597f3633c75a1f98, type: 3}
m_Name: Pulver
m_EditorClassIdentifier: Unity.Timeline::UnityEngine.Timeline.AnimationTrack
m_Version: 3
m_AnimClip: {fileID: 0}
m_Locked: 0
m_Muted: 0
m_CustomPlayableFullTypename:
m_Curves: {fileID: 0}
m_Parent: {fileID: 11400000}
m_Children: []
m_Clips:
- m_Version: 1
m_Start: 0
m_ClipIn: 0
m_Asset: {fileID: -744416834715362379}
m_Duration: 0.8333333333333334
m_TimeScale: 1
m_ParentTrack: {fileID: -1185821560092742700}
m_EaseInDuration: 0
m_EaseOutDuration: 0
m_BlendInDuration: -1
m_BlendOutDuration: -1
m_MixInCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 1
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
m_MixOutCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 1
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
m_BlendInCurveMode: 0
m_BlendOutCurveMode: 0
m_ExposedParameterNames: []
m_AnimationCurves: {fileID: 0}
m_Recordable: 0
m_PostExtrapolationMode: 1
m_PreExtrapolationMode: 1
m_PostExtrapolationTime: Infinity
m_PreExtrapolationTime: 0
m_DisplayName: Pulver_Cucumbatacc
m_Markers:
m_Objects: []
m_InfiniteClipPreExtrapolation: 0
m_InfiniteClipPostExtrapolation: 0
m_InfiniteClipOffsetPosition: {x: 0, y: 0, z: 0}
m_InfiniteClipOffsetEulerAngles: {x: 0, y: 0, z: 0}
m_InfiniteClipTimeOffset: 0
m_InfiniteClipRemoveOffset: 0
m_InfiniteClipApplyFootIK: 1
mInfiniteClipLoop: 0
m_MatchTargetFields: 63
m_Position: {x: 0, y: 0, z: 0}
m_EulerAngles: {x: 0, y: 0, z: 0}
m_AvatarMask: {fileID: 0}
m_ApplyAvatarMask: 1
m_TrackOffset: 0
m_InfiniteClip: {fileID: 0}
m_OpenClipOffsetRotation: {x: 0, y: 0, z: 0, w: 1}
m_Rotation: {x: 0, y: 0, z: 0, w: 1}
m_ApplyOffsets: 0
--- !u!114 &-744416834715362379
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 030f85c3f73729f4f976f66ffb23b875, type: 3}
m_Name: AnimationPlayableAsset
m_EditorClassIdentifier: Unity.Timeline::UnityEngine.Timeline.AnimationPlayableAsset
m_Clip: {fileID: 7400000, guid: 09d7dd4e84cbed54bb4ca4e63ad0c6fa, type: 2}
m_Position: {x: 0, y: 0, z: 0}
m_EulerAngles: {x: 0, y: 0, z: 0}
m_UseTrackMatchFields: 1
m_MatchTargetFields: 63
m_RemoveStartOffset: 1
m_ApplyFootIK: 1
m_Loop: 0
m_Version: 1
m_Rotation: {x: 0, y: 0, z: 0, w: 1}
--- !u!114 &-461426874464204690
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2a16748d9461eae46a725db9776d5390, type: 3}
m_Name: Markers
m_EditorClassIdentifier: Unity.Timeline::UnityEngine.Timeline.MarkerTrack
m_Version: 3
m_AnimClip: {fileID: 0}
m_Locked: 0
m_Muted: 0
m_CustomPlayableFullTypename:
m_Curves: {fileID: 0}
m_Parent: {fileID: 11400000}
m_Children: []
m_Clips: []
m_Markers:
m_Objects: []
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bfda56da833e2384a9677cd3c976a436, type: 3}
m_Name: PulverCucumberSmack
m_EditorClassIdentifier: Unity.Timeline::UnityEngine.Timeline.TimelineAsset
m_Version: 0
m_Tracks:
- {fileID: -1185821560092742700}
- {fileID: 1662278050270751211}
m_FixedDuration: 0
m_EditorSettings:
m_Framerate: 60
m_ScenePreview: 1
m_DurationMode: 0
m_MarkerTrack: {fileID: -461426874464204690}
--- !u!114 &1662278050270751211
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d21dcc2386d650c4597f3633c75a1f98, type: 3}
m_Name: Animation Track (2)
m_EditorClassIdentifier: Unity.Timeline::UnityEngine.Timeline.AnimationTrack
m_Version: 3
m_AnimClip: {fileID: 0}
m_Locked: 0
m_Muted: 0
m_CustomPlayableFullTypename:
m_Curves: {fileID: 0}
m_Parent: {fileID: 11400000}
m_Children: []
m_Clips: []
m_Markers:
m_Objects: []
m_InfiniteClipPreExtrapolation: 1
m_InfiniteClipPostExtrapolation: 1
m_InfiniteClipOffsetPosition: {x: -36.32, y: 104.64, z: 0}
m_InfiniteClipOffsetEulerAngles: {x: -0, y: 0, z: 0}
m_InfiniteClipTimeOffset: 0
m_InfiniteClipRemoveOffset: 0
m_InfiniteClipApplyFootIK: 1
mInfiniteClipLoop: 0
m_MatchTargetFields: 63
m_Position: {x: 0, y: 0, z: 0}
m_EulerAngles: {x: 0, y: 0, z: 0}
m_AvatarMask: {fileID: 0}
m_ApplyAvatarMask: 1
m_TrackOffset: 0
m_InfiniteClip: {fileID: 7057870124182637150}
m_OpenClipOffsetRotation: {x: 0, y: 0, z: 0, w: 1}
m_Rotation: {x: 0, y: 0, z: 0, w: 1}
m_ApplyOffsets: 0
--- !u!74 &7057870124182637150
AnimationClip:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Recorded (1)
serializedVersion: 7
m_Legacy: 0
m_Compressed: 0
m_UseHighQualityCurve: 1
m_RotationCurves: []
m_CompressedRotationCurves: []
m_EulerCurves: []
m_PositionCurves:
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: {x: 0, y: -0.40000153, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
weightedMode: 0
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
- serializedVersion: 3
time: 0.23333333
value: {x: 0, y: -0.40000153, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
weightedMode: 0
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
- serializedVersion: 3
time: 0.35
value: {x: -5.6000023, y: 3, z: 0}
inSlope: {x: -48.00001, y: 0, z: 0}
outSlope: {x: -48.00001, y: 0, z: 0}
tangentMode: 0
weightedMode: 0
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
- serializedVersion: 3
time: 0.45
value: {x: -10.400002, y: -1.199997, z: 0}
inSlope: {x: -25.999998, y: -55.99996, z: 0}
outSlope: {x: -25.999998, y: -55.99996, z: 0}
tangentMode: 0
weightedMode: 0
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
- serializedVersion: 3
time: 0.65
value: {x: -13.400002, y: -14.599998, z: 0}
inSlope: {x: -5.6470795, y: 0, z: 0}
outSlope: {x: -5.6470795, y: 0, z: 0}
tangentMode: 0
weightedMode: 0
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
- serializedVersion: 3
time: 0.73333335
value: {x: -13.800003, y: -13.599998, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
weightedMode: 0
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
- serializedVersion: 3
time: 0.8333333
value: {x: -13.800003, y: -14.799995, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
weightedMode: 0
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
- serializedVersion: 3
time: 0.96666664
value: {x: -14.800003, y: -14.199997, z: 0}
inSlope: {x: -6.3999925, y: 0, z: 0}
outSlope: {x: -6.3999925, y: 0, z: 0}
tangentMode: 0
weightedMode: 0
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
- serializedVersion: 3
time: 1.0833334
value: {x: -15.400002, y: -15.199997, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
weightedMode: 0
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
path:
m_ScaleCurves: []
m_FloatCurves:
- serializedVersion: 2
curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: Infinity
outSlope: Infinity
tangentMode: 103
weightedMode: 0
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 1.1666666
value: 1
inSlope: Infinity
outSlope: Infinity
tangentMode: 103
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_Enabled
path:
classID: 114
script: {fileID: 11500000, guid: 73d6494a73174ffabc6a7d3089d51e73, type: 3}
flags: 0
- serializedVersion: 2
curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: Infinity
outSlope: Infinity
tangentMode: 103
weightedMode: 0
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 1.1666666
value: 1
inSlope: Infinity
outSlope: Infinity
tangentMode: 103
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_Enabled
path:
classID: 114
script: {fileID: 11500000, guid: 7846448751da4bdbaaa5cb87890dca42, type: 3}
flags: 0
- serializedVersion: 2
curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: Infinity
outSlope: Infinity
tangentMode: 103
weightedMode: 0
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 1.1666666
value: 1
inSlope: Infinity
outSlope: Infinity
tangentMode: 103
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_Enabled
path:
classID: 114
script: {fileID: 11500000, guid: 1101f6c4eb04423b89dc78dc7c9f1aae, type: 3}
flags: 0
m_PPtrCurves: []
m_SampleRate: 60
m_WrapMode: 0
m_Bounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 0, y: 0, z: 0}
m_ClipBindingConstant:
genericBindings:
- serializedVersion: 2
path: 0
attribute: 1
script: {fileID: 0}
typeID: 4
customType: 0
isPPtrCurve: 0
isIntCurve: 0
isSerializeReferenceCurve: 0
- serializedVersion: 2
path: 0
attribute: 3305885265
script: {fileID: 11500000, guid: 73d6494a73174ffabc6a7d3089d51e73, type: 3}
typeID: 114
customType: 24
isPPtrCurve: 0
isIntCurve: 0
isSerializeReferenceCurve: 0
- serializedVersion: 2
path: 0
attribute: 3305885265
script: {fileID: 11500000, guid: 7846448751da4bdbaaa5cb87890dca42, type: 3}
typeID: 114
customType: 24
isPPtrCurve: 0
isIntCurve: 0
isSerializeReferenceCurve: 0
- serializedVersion: 2
path: 0
attribute: 3305885265
script: {fileID: 11500000, guid: 1101f6c4eb04423b89dc78dc7c9f1aae, type: 3}
typeID: 114
customType: 24
isPPtrCurve: 0
isIntCurve: 0
isSerializeReferenceCurve: 0
pptrCurveMapping: []
m_AnimationClipSettings:
serializedVersion: 2
m_AdditiveReferencePoseClip: {fileID: 0}
m_AdditiveReferencePoseTime: 0
m_StartTime: 0
m_StopTime: 1.1666666
m_OrientationOffsetY: 0
m_Level: 0
m_CycleOffset: 0
m_HasAdditiveReferencePose: 0
m_LoopTime: 0
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 0
m_LoopBlendPositionXZ: 0
m_KeepOriginalOrientation: 0
m_KeepOriginalPositionY: 1
m_KeepOriginalPositionXZ: 0
m_HeightFromFeet: 0
m_Mirror: 0
m_EditorCurves:
- serializedVersion: 2
curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.23333333
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.35
value: -5.6000023
inSlope: -48.00001
outSlope: -48.00001
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.45
value: -10.400002
inSlope: -25.999998
outSlope: -25.999998
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.65
value: -13.400002
inSlope: -5.6470795
outSlope: -5.6470795
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.73333335
value: -13.800003
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.8333333
value: -13.800003
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.96666664
value: -14.800003
inSlope: -6.3999925
outSlope: -6.3999925
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 1.0833334
value: -15.400002
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalPosition.x
path:
classID: 4
script: {fileID: 0}
flags: 0
- serializedVersion: 2
curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: -0.40000153
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.23333333
value: -0.40000153
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.35
value: 3
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.45
value: -1.199997
inSlope: -55.99996
outSlope: -55.99996
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.65
value: -14.599998
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.73333335
value: -13.599998
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.8333333
value: -14.799995
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.96666664
value: -14.199997
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 1.0833334
value: -15.199997
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalPosition.y
path:
classID: 4
script: {fileID: 0}
flags: 0
- serializedVersion: 2
curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.23333333
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.35
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.45
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.65
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.73333335
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.8333333
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.96666664
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 1.0833334
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalPosition.z
path:
classID: 4
script: {fileID: 0}
flags: 0
- serializedVersion: 2
curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: Infinity
outSlope: Infinity
tangentMode: 103
weightedMode: 0
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 1.1666666
value: 1
inSlope: Infinity
outSlope: Infinity
tangentMode: 103
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_Enabled
path:
classID: 114
script: {fileID: 11500000, guid: 73d6494a73174ffabc6a7d3089d51e73, type: 3}
flags: 0
- serializedVersion: 2
curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: Infinity
outSlope: Infinity
tangentMode: 103
weightedMode: 0
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 1.1666666
value: 1
inSlope: Infinity
outSlope: Infinity
tangentMode: 103
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_Enabled
path:
classID: 114
script: {fileID: 11500000, guid: 7846448751da4bdbaaa5cb87890dca42, type: 3}
flags: 0
- serializedVersion: 2
curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: Infinity
outSlope: Infinity
tangentMode: 103
weightedMode: 0
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 1.1666666
value: 1
inSlope: Infinity
outSlope: Infinity
tangentMode: 103
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_Enabled
path:
classID: 114
script: {fileID: 11500000, guid: 1101f6c4eb04423b89dc78dc7c9f1aae, type: 3}
flags: 0
m_EulerEditorCurves: []
m_HasGenericRootTransform: 1
m_HasMotionFloatCurves: 0
m_Events: []

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 27f5954bda3e24b48b33e5a6605eb33f
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,811 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-7584736085941489071
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d21dcc2386d650c4597f3633c75a1f98, type: 3}
m_Name: Animation Track
m_EditorClassIdentifier: Unity.Timeline::UnityEngine.Timeline.AnimationTrack
m_Version: 3
m_AnimClip: {fileID: 0}
m_Locked: 0
m_Muted: 0
m_CustomPlayableFullTypename:
m_Curves: {fileID: 0}
m_Parent: {fileID: 11400000}
m_Children: []
m_Clips: []
m_Markers:
m_Objects: []
m_InfiniteClipPreExtrapolation: 0
m_InfiniteClipPostExtrapolation: 0
m_InfiniteClipOffsetPosition: {x: 0, y: 0, z: 0}
m_InfiniteClipOffsetEulerAngles: {x: 0, y: 0, z: 0}
m_InfiniteClipTimeOffset: 0
m_InfiniteClipRemoveOffset: 0
m_InfiniteClipApplyFootIK: 1
mInfiniteClipLoop: 0
m_MatchTargetFields: 63
m_Position: {x: 0, y: 0, z: 0}
m_EulerAngles: {x: 0, y: 0, z: 0}
m_AvatarMask: {fileID: 0}
m_ApplyAvatarMask: 1
m_TrackOffset: 0
m_InfiniteClip: {fileID: 0}
m_OpenClipOffsetRotation: {x: 0, y: 0, z: 0, w: 1}
m_Rotation: {x: 0, y: 0, z: 0, w: 1}
m_ApplyOffsets: 0
--- !u!114 &-7231857257271738743
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d21dcc2386d650c4597f3633c75a1f98, type: 3}
m_Name: Animation Track (2)
m_EditorClassIdentifier: Unity.Timeline::UnityEngine.Timeline.AnimationTrack
m_Version: 3
m_AnimClip: {fileID: 0}
m_Locked: 0
m_Muted: 0
m_CustomPlayableFullTypename:
m_Curves: {fileID: 0}
m_Parent: {fileID: 11400000}
m_Children: []
m_Clips: []
m_Markers:
m_Objects: []
m_InfiniteClipPreExtrapolation: 1
m_InfiniteClipPostExtrapolation: 1
m_InfiniteClipOffsetPosition: {x: -3.4, y: 0, z: 0}
m_InfiniteClipOffsetEulerAngles: {x: -0, y: 0, z: 0}
m_InfiniteClipTimeOffset: 0
m_InfiniteClipRemoveOffset: 0
m_InfiniteClipApplyFootIK: 1
mInfiniteClipLoop: 0
m_MatchTargetFields: 63
m_Position: {x: 0, y: 0, z: 0}
m_EulerAngles: {x: 0, y: 0, z: 0}
m_AvatarMask: {fileID: 0}
m_ApplyAvatarMask: 1
m_TrackOffset: 0
m_InfiniteClip: {fileID: -6922421277477507865}
m_OpenClipOffsetRotation: {x: 0, y: 0, z: 0, w: 1}
m_Rotation: {x: 0, y: 0, z: 0, w: 1}
m_ApplyOffsets: 0
--- !u!74 &-7150935952859310220
AnimationClip:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Recorded (1)
serializedVersion: 7
m_Legacy: 0
m_Compressed: 0
m_UseHighQualityCurve: 1
m_RotationCurves: []
m_CompressedRotationCurves: []
m_EulerCurves: []
m_PositionCurves:
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0.11666667
value: {x: 0, y: 0, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
weightedMode: 0
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
- serializedVersion: 3
time: 0.18333334
value: {x: 3, y: 2.2000046, z: 0}
inSlope: {x: 31.500008, y: 0, z: 0}
outSlope: {x: 31.500008, y: 0, z: 0}
tangentMode: 0
weightedMode: 0
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
- serializedVersion: 3
time: 0.25
value: {x: 4.200001, y: -1.3999939, z: 0}
inSlope: {x: 3.200012, y: -57.599976, z: 0}
outSlope: {x: 3.200012, y: -57.599976, z: 0}
tangentMode: 0
weightedMode: 0
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
- serializedVersion: 3
time: 0.43333334
value: {x: 4.4000015, y: -12.399994, z: 0}
inSlope: {x: 3.0000045, y: 0, z: 0}
outSlope: {x: 3.0000045, y: 0, z: 0}
tangentMode: 0
weightedMode: 0
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
- serializedVersion: 3
time: 0.51666665
value: {x: 5.000002, y: -11.199997, z: 0}
inSlope: {x: 9.333332, y: 0, z: 0}
outSlope: {x: 9.333332, y: 0, z: 0}
tangentMode: 0
weightedMode: 0
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
- serializedVersion: 3
time: 0.5833333
value: {x: 5.800001, y: -12.799995, z: 0}
inSlope: {x: 7.199992, y: 0, z: 0}
outSlope: {x: 7.199992, y: 0, z: 0}
tangentMode: 0
weightedMode: 0
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
- serializedVersion: 3
time: 0.68333334
value: {x: 6.200001, y: -11.999992, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
weightedMode: 0
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
- serializedVersion: 3
time: 0.76666665
value: {x: 6.200001, y: -12.799995, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
weightedMode: 0
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334}
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
path:
m_ScaleCurves: []
m_FloatCurves: []
m_PPtrCurves: []
m_SampleRate: 60
m_WrapMode: 0
m_Bounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 0, y: 0, z: 0}
m_ClipBindingConstant:
genericBindings:
- serializedVersion: 2
path: 0
attribute: 1
script: {fileID: 0}
typeID: 4
customType: 0
isPPtrCurve: 0
isIntCurve: 0
isSerializeReferenceCurve: 0
pptrCurveMapping: []
m_AnimationClipSettings:
serializedVersion: 2
m_AdditiveReferencePoseClip: {fileID: 0}
m_AdditiveReferencePoseTime: 0
m_StartTime: 0
m_StopTime: 0.76666665
m_OrientationOffsetY: 0
m_Level: 0
m_CycleOffset: 0
m_HasAdditiveReferencePose: 0
m_LoopTime: 0
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 0
m_LoopBlendPositionXZ: 0
m_KeepOriginalOrientation: 0
m_KeepOriginalPositionY: 1
m_KeepOriginalPositionXZ: 0
m_HeightFromFeet: 0
m_Mirror: 0
m_EditorCurves:
- serializedVersion: 2
curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0.11666667
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.18333334
value: 3
inSlope: 31.500008
outSlope: 31.500008
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.25
value: 4.200001
inSlope: 3.200012
outSlope: 3.200012
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.43333334
value: 4.4000015
inSlope: 3.0000045
outSlope: 3.0000045
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.51666665
value: 5.000002
inSlope: 9.333332
outSlope: 9.333332
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.5833333
value: 5.800001
inSlope: 7.199992
outSlope: 7.199992
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.68333334
value: 6.200001
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.76666665
value: 6.200001
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalPosition.x
path:
classID: 4
script: {fileID: 0}
flags: 0
- serializedVersion: 2
curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0.11666667
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.18333334
value: 2.2000046
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.25
value: -1.3999939
inSlope: -57.599976
outSlope: -57.599976
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.43333334
value: -12.399994
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.51666665
value: -11.199997
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.5833333
value: -12.799995
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.68333334
value: -11.999992
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.76666665
value: -12.799995
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalPosition.y
path:
classID: 4
script: {fileID: 0}
flags: 0
- serializedVersion: 2
curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0.11666667
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.18333334
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.25
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.43333334
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.51666665
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.5833333
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.68333334
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 0.76666665
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalPosition.z
path:
classID: 4
script: {fileID: 0}
flags: 0
m_EulerEditorCurves: []
m_HasGenericRootTransform: 1
m_HasMotionFloatCurves: 0
m_Events: []
--- !u!74 &-6922421277477507865
AnimationClip:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Recorded
serializedVersion: 7
m_Legacy: 0
m_Compressed: 0
m_UseHighQualityCurve: 1
m_RotationCurves: []
m_CompressedRotationCurves: []
m_EulerCurves: []
m_PositionCurves:
- curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: {x: -39.2, y: 92, z: 0}
inSlope: {x: 0, y: 0, z: 0}
outSlope: {x: 0, y: 0, z: 0}
tangentMode: 0
weightedMode: 0
inWeight: {x: 0, y: 0.33333334, z: 0.33333334}
outWeight: {x: 0, y: 0.33333334, z: 0.33333334}
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
path:
m_ScaleCurves: []
m_FloatCurves: []
m_PPtrCurves: []
m_SampleRate: 60
m_WrapMode: 0
m_Bounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 0, y: 0, z: 0}
m_ClipBindingConstant:
genericBindings:
- serializedVersion: 2
path: 0
attribute: 1
script: {fileID: 0}
typeID: 4
customType: 0
isPPtrCurve: 0
isIntCurve: 0
isSerializeReferenceCurve: 0
pptrCurveMapping: []
m_AnimationClipSettings:
serializedVersion: 2
m_AdditiveReferencePoseClip: {fileID: 0}
m_AdditiveReferencePoseTime: 0
m_StartTime: 0
m_StopTime: 0
m_OrientationOffsetY: 0
m_Level: 0
m_CycleOffset: 0
m_HasAdditiveReferencePose: 0
m_LoopTime: 0
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 0
m_LoopBlendPositionXZ: 0
m_KeepOriginalOrientation: 0
m_KeepOriginalPositionY: 1
m_KeepOriginalPositionXZ: 0
m_HeightFromFeet: 0
m_Mirror: 0
m_EditorCurves:
- serializedVersion: 2
curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: -39.2
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalPosition.x
path:
classID: 4
script: {fileID: 0}
flags: 0
- serializedVersion: 2
curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 92
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalPosition.y
path:
classID: 4
script: {fileID: 0}
flags: 0
- serializedVersion: 2
curve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 136
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
attribute: m_LocalPosition.z
path:
classID: 4
script: {fileID: 0}
flags: 0
m_EulerEditorCurves: []
m_HasGenericRootTransform: 1
m_HasMotionFloatCurves: 0
m_Events: []
--- !u!114 &-4100604165561699402
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d21dcc2386d650c4597f3633c75a1f98, type: 3}
m_Name: Animation Track (3)
m_EditorClassIdentifier: Unity.Timeline::UnityEngine.Timeline.AnimationTrack
m_Version: 3
m_AnimClip: {fileID: 0}
m_Locked: 0
m_Muted: 0
m_CustomPlayableFullTypename:
m_Curves: {fileID: 0}
m_Parent: {fileID: 11400000}
m_Children: []
m_Clips: []
m_Markers:
m_Objects: []
m_InfiniteClipPreExtrapolation: 1
m_InfiniteClipPostExtrapolation: 1
m_InfiniteClipOffsetPosition: {x: -32.90073, y: 103.51327, z: 0}
m_InfiniteClipOffsetEulerAngles: {x: -0, y: 0, z: 0}
m_InfiniteClipTimeOffset: 0
m_InfiniteClipRemoveOffset: 0
m_InfiniteClipApplyFootIK: 1
mInfiniteClipLoop: 0
m_MatchTargetFields: 63
m_Position: {x: 0, y: 0, z: 0}
m_EulerAngles: {x: 0, y: 0, z: 0}
m_AvatarMask: {fileID: 0}
m_ApplyAvatarMask: 1
m_TrackOffset: 0
m_InfiniteClip: {fileID: -7150935952859310220}
m_OpenClipOffsetRotation: {x: 0, y: 0, z: 0, w: 1}
m_Rotation: {x: 0, y: 0, z: 0, w: 1}
m_ApplyOffsets: 0
--- !u!114 &-2395336864975438248
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d21dcc2386d650c4597f3633c75a1f98, type: 3}
m_Name: Animation Track (1)
m_EditorClassIdentifier: Unity.Timeline::UnityEngine.Timeline.AnimationTrack
m_Version: 3
m_AnimClip: {fileID: 0}
m_Locked: 0
m_Muted: 0
m_CustomPlayableFullTypename:
m_Curves: {fileID: 0}
m_Parent: {fileID: 11400000}
m_Children: []
m_Clips:
- m_Version: 1
m_Start: 0
m_ClipIn: 0
m_Asset: {fileID: 3115908604919352715}
m_Duration: 0.8333333333333334
m_TimeScale: 1
m_ParentTrack: {fileID: -2395336864975438248}
m_EaseInDuration: 0
m_EaseOutDuration: 0
m_BlendInDuration: -1
m_BlendOutDuration: -1
m_MixInCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 1
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
m_MixOutCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 1
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
m_BlendInCurveMode: 0
m_BlendOutCurveMode: 0
m_ExposedParameterNames: []
m_AnimationCurves: {fileID: 0}
m_Recordable: 0
m_PostExtrapolationMode: 1
m_PreExtrapolationMode: 1
m_PostExtrapolationTime: Infinity
m_PreExtrapolationTime: 0
m_DisplayName: Pulver_Cucumbatacc
m_Markers:
m_Objects: []
m_InfiniteClipPreExtrapolation: 0
m_InfiniteClipPostExtrapolation: 0
m_InfiniteClipOffsetPosition: {x: 0, y: 0, z: 0}
m_InfiniteClipOffsetEulerAngles: {x: 0, y: 0, z: 0}
m_InfiniteClipTimeOffset: 0
m_InfiniteClipRemoveOffset: 0
m_InfiniteClipApplyFootIK: 1
mInfiniteClipLoop: 0
m_MatchTargetFields: 63
m_Position: {x: 0, y: 0, z: 0}
m_EulerAngles: {x: 0, y: 0, z: 0}
m_AvatarMask: {fileID: 0}
m_ApplyAvatarMask: 1
m_TrackOffset: 0
m_InfiniteClip: {fileID: 0}
m_OpenClipOffsetRotation: {x: 0, y: 0, z: 0, w: 1}
m_Rotation: {x: 0, y: 0, z: 0, w: 1}
m_ApplyOffsets: 0
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bfda56da833e2384a9677cd3c976a436, type: 3}
m_Name: PulverCucumberSmack2
m_EditorClassIdentifier: Unity.Timeline::UnityEngine.Timeline.TimelineAsset
m_Version: 0
m_Tracks:
- {fileID: -7584736085941489071}
- {fileID: -2395336864975438248}
- {fileID: -7231857257271738743}
- {fileID: -4100604165561699402}
m_FixedDuration: 0
m_EditorSettings:
m_Framerate: 60
m_ScenePreview: 1
m_DurationMode: 0
m_MarkerTrack: {fileID: 0}
--- !u!114 &3115908604919352715
MonoBehaviour:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 030f85c3f73729f4f976f66ffb23b875, type: 3}
m_Name: AnimationPlayableAsset
m_EditorClassIdentifier: Unity.Timeline::UnityEngine.Timeline.AnimationPlayableAsset
m_Clip: {fileID: 7400000, guid: 09d7dd4e84cbed54bb4ca4e63ad0c6fa, type: 2}
m_Position: {x: 0, y: 0, z: 0}
m_EulerAngles: {x: 0, y: 0, z: 0}
m_UseTrackMatchFields: 1
m_MatchTargetFields: 63
m_RemoveStartOffset: 1
m_ApplyFootIK: 1
m_Loop: 0
m_Version: 1
m_Rotation: {x: 0, y: 0, z: 0, w: 1}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: dd9566026364e814a8dad109e6c365ca
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -313,6 +313,14 @@ PrefabInstance:
propertyPath: m_Layer
value: 7
objectReference: {fileID: 0}
- target: {fileID: 6109476811019011833, guid: 361ccc9ef82acef4784b24b72013d971, type: 3}
propertyPath: m_Size.x
value: 3.8700001
objectReference: {fileID: 0}
- target: {fileID: 6109476811019011833, guid: 361ccc9ef82acef4784b24b72013d971, type: 3}
propertyPath: m_Size.y
value: 7.55122
objectReference: {fileID: 0}
- target: {fileID: 6109476811019011833, guid: 361ccc9ef82acef4784b24b72013d971, type: 3}
propertyPath: m_SortingOrder
value: 1

View File

@@ -136,7 +136,7 @@ MonoBehaviour:
radius: 2
height: 2
canMove: 1
maxSpeed: 15
maxSpeed: 30
gravity: {x: 0, y: 0, z: 0}
groundMask:
serializedVersion: 2
@@ -236,6 +236,8 @@ SpriteRenderer:
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_ForceMeshLod: -1
m_MeshLodSelectionBias: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
@@ -257,6 +259,7 @@ SpriteRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 2

View File

@@ -1,5 +1,51 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &1646387898454772943
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7371967679236352629}
- component: {fileID: 2280359367130513804}
m_Layer: 0
m_Name: PulverMoveTarget
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &7371967679236352629
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1646387898454772943}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: -4.4615383, y: 0.61538696, z: 0}
m_LocalScale: {x: 0.7692308, y: 0.7692308, z: 0.7692308}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 4937390562043858043}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &2280359367130513804
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1646387898454772943}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2bcf343b3ef74f0fb3c64be6fd2893b6, type: 3}
m_Name:
m_EditorClassIdentifier: AppleHillsScripts::Interactions.CharacterMoveToTarget
characterType: 2
positionOffset: {x: 0, y: 0, z: 1}
--- !u!1 &3591802784221671576
GameObject:
m_ObjectHideFlags: 0
@@ -94,6 +140,11 @@ GameObject:
- component: {fileID: 4937390562043858043}
- component: {fileID: 2720557426779044373}
- component: {fileID: 8897661028274890141}
- component: {fileID: 8437452310832126615}
- component: {fileID: 492578671844741631}
- component: {fileID: 8984729148657672365}
- component: {fileID: 1569498917964935965}
- component: {fileID: 3871210969445384207}
m_Layer: 10
m_Name: BallTree
m_TagString: Untagged
@@ -115,6 +166,7 @@ Transform:
m_ConstrainProportionsScale: 1
m_Children:
- {fileID: 6631072601870453588}
- {fileID: 7371967679236352629}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &2720557426779044373
@@ -137,6 +189,8 @@ SpriteRenderer:
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_ForceMeshLod: -1
m_MeshLodSelectionBias: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
@@ -158,6 +212,7 @@ SpriteRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 1
@@ -218,3 +273,115 @@ BoxCollider2D:
m_AutoTiling: 0
m_Size: {x: 3.437712, y: 7.532383}
m_EdgeRadius: 0
--- !u!114 &8437452310832126615
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7379304988657006554}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 73d6494a73174ffabc6a7d3089d51e73, type: 3}
m_Name:
m_EditorClassIdentifier:
isOneTime: 0
cooldown: -1
characterToInteract: 2
interactionStarted:
m_PersistentCalls:
m_Calls: []
interactionInterrupted:
m_PersistentCalls:
m_Calls: []
characterArrived:
m_PersistentCalls:
m_Calls: []
interactionComplete:
m_PersistentCalls:
m_Calls: []
--- !u!114 &492578671844741631
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7379304988657006554}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1101f6c4eb04423b89dc78dc7c9f1aae, type: 3}
m_Name:
m_EditorClassIdentifier:
stepData: {fileID: 11400000, guid: 8ac614a698631554ab8ac39aed04a189, type: 2}
puzzleIndicator: {fileID: 0}
drawPromptRangeGizmo: 1
--- !u!114 &8984729148657672365
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7379304988657006554}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 42e77a0c97604b6eb7674e58726c831a, type: 3}
m_Name:
m_EditorClassIdentifier: AppleHillsScripts::Interactions.InteractionTimelineAction
respondToEvents: 04000000
pauseInteractionFlow: 1
playableDirector: {fileID: 0}
timelineMappings:
- eventType: 4
timelines: []
bindPlayerCharacter: 0
bindPulverCharacter: 0
playerTrackName:
pulverTrackName:
timeoutSeconds: 30
loopLast: 0
loopAll: 0
--- !u!320 &1569498917964935965
PlayableDirector:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7379304988657006554}
m_Enabled: 1
serializedVersion: 3
m_PlayableAsset: {fileID: 11400000, guid: dd9566026364e814a8dad109e6c365ca, type: 2}
m_InitialState: 0
m_WrapMode: 2
m_DirectorUpdateMode: 1
m_InitialTime: 0
m_SceneBindings:
- key: {fileID: -7584736085941489071, guid: dd9566026364e814a8dad109e6c365ca, type: 2}
value: {fileID: 3871210969445384207}
- key: {fileID: -2395336864975438248, guid: dd9566026364e814a8dad109e6c365ca, type: 2}
value: {fileID: 0}
- key: {fileID: -7231857257271738743, guid: dd9566026364e814a8dad109e6c365ca, type: 2}
value: {fileID: 0}
m_ExposedReferences:
m_References: []
--- !u!95 &3871210969445384207
Animator:
serializedVersion: 7
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7379304988657006554}
m_Enabled: 1
m_Avatar: {fileID: 0}
m_Controller: {fileID: 0}
m_CullingMode: 0
m_UpdateMode: 0
m_ApplyRootMotion: 0
m_LinearVelocityBlending: 0
m_StabilizeFeet: 0
m_AnimatePhysics: 0
m_WarningMessage:
m_HasTransformHierarchy: 1
m_AllowConstantClipSamplingOptimization: 1
m_KeepAnimatorStateOnDisable: 0
m_WriteDefaultValuesOnDisable: 0

View File

@@ -0,0 +1,58 @@
using UnityEngine;
namespace Interactions
{
/// <summary>
/// Defines a target position for character movement during interaction.
/// Attach this to an interactable object's child to specify where
/// characters should move during interaction rather than using the default calculations.
/// </summary>
public class CharacterMoveToTarget : MonoBehaviour
{
[Tooltip("Which character this target position is for")]
public CharacterToInteract characterType = CharacterToInteract.Pulver;
[Tooltip("Optional offset from this transform's position")]
public Vector3 positionOffset = Vector3.zero;
/// <summary>
/// Get the target position for this character to move to
/// </summary>
public Vector3 GetTargetPosition()
{
return transform.position + positionOffset;
}
#if UNITY_EDITOR
private void OnDrawGizmos()
{
// Draw a different colored sphere based on which character this target is for
switch (characterType)
{
case CharacterToInteract.Trafalgar:
Gizmos.color = new Color(0f, 0.5f, 1f, 0.8f); // Blue for player
break;
case CharacterToInteract.Pulver:
Gizmos.color = new Color(1f, 0.5f, 0f, 0.8f); // Orange for follower
break;
case CharacterToInteract.Both:
Gizmos.color = new Color(0.7f, 0f, 0.7f, 0.8f); // Purple for both
break;
default:
Gizmos.color = new Color(0.5f, 0.5f, 0.5f, 0.8f); // Gray for none
break;
}
Vector3 targetPos = GetTargetPosition();
Gizmos.DrawSphere(targetPos, 0.2f);
// Draw a line from the parent interactable to this target
Interactable parentInteractable = GetComponentInParent<Interactable>();
if (parentInteractable != null)
{
Gizmos.DrawLine(parentInteractable.transform.position, targetPos);
}
}
#endif
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2bcf343b3ef74f0fb3c64be6fd2893b6
timeCreated: 1759744130

View File

@@ -1,22 +1,27 @@
using Input;
using UnityEngine;
using System;
using System.Collections.Generic;
using UnityEngine.Events;
using System.Threading.Tasks;
namespace Interactions
{
public enum CharacterToInteract
{
None,
Trafalgar,
Pulver
Pulver,
Both
}
/// <summary>
/// Represents an interactable object that can respond to tap input events.
/// </summary>
public class Interactable : MonoBehaviour, ITouchInputConsumer
{
[Header("Interaction Settings")]
public bool isOneTime = false;
public bool isOneTime;
public float cooldown = -1f;
public CharacterToInteract characterToInteract = CharacterToInteract.Pulver;
@@ -30,15 +35,64 @@ namespace Interactions
private bool _interactionInProgress;
private PlayerTouchController _playerRef;
private FollowerController _followerController;
private bool _isActive = true;
private InteractionEventType _currentEventType;
// Action component system
private List<InteractionActionBase> _registeredActions = new List<InteractionActionBase>();
private void Awake()
{
// Subscribe to interactionComplete event
interactionComplete.AddListener(OnInteractionComplete);
}
/// <summary>
/// Register an action component with this interactable
/// </summary>
public void RegisterAction(InteractionActionBase action)
{
if (!_registeredActions.Contains(action))
{
_registeredActions.Add(action);
}
}
/// <summary>
/// Unregister an action component from this interactable
/// </summary>
public void UnregisterAction(InteractionActionBase action)
{
_registeredActions.Remove(action);
}
/// <summary>
/// Dispatch an interaction event to all registered actions and await their completion
/// </summary>
private async Task DispatchEventAsync(InteractionEventType eventType)
{
_currentEventType = eventType;
// Collect all tasks from actions that want to respond
List<Task<bool>> tasks = new List<Task<bool>>();
foreach (var action in _registeredActions)
{
Task<bool> task = action.OnInteractionEvent(eventType, _playerRef, _followerController);
if (task != null)
{
tasks.Add(task);
}
}
if (tasks.Count > 0)
{
// Wait for all tasks to complete
await Task.WhenAll(tasks);
}
// If no tasks were added, the method will complete immediately (no need for await)
}
/// <summary>
/// Handles tap input. Triggers interaction logic.
/// </summary>
@@ -50,11 +104,12 @@ namespace Interactions
return;
}
Debug.Log($"[Interactable] OnTap at {worldPosition} on {gameObject.name}");
// Broadcast interaction started event
TryInteract();
// Start the interaction process asynchronously
_ = TryInteractAsync();
}
public void TryInteract()
private async Task TryInteractAsync()
{
_interactionInProgress = true;
@@ -63,68 +118,278 @@ namespace Interactions
interactionStarted?.Invoke(_playerRef, _followerController);
// Dispatch the InteractionStarted event to action components
await DispatchEventAsync(InteractionEventType.InteractionStarted);
// After all InteractionStarted actions complete, proceed to player movement
await StartPlayerMovementAsync();
}
private async Task StartPlayerMovementAsync()
{
if (_playerRef == null)
{
Debug.Log($"[Interactable] Player character could not be found. Aborting interaction.");
interactionInterrupted.Invoke();
await DispatchEventAsync(InteractionEventType.InteractionInterrupted);
return;
}
// If characterToInteract is None, immediately trigger the characterArrived event
if (characterToInteract == CharacterToInteract.None)
{
await BroadcastCharacterArrivedAsync();
return;
}
// Compute closest point on the interaction radius
Vector3 interactablePos = transform.position;
Vector3 playerPos = _playerRef.transform.position;
float stopDistance = characterToInteract == CharacterToInteract.Pulver
? GameManager.Instance.PlayerStopDistance
: GameManager.Instance.PlayerStopDistanceDirectInteraction;
Vector3 toPlayer = (playerPos - interactablePos).normalized;
Vector3 stopPoint = interactablePos + toPlayer * stopDistance;
// Check for a CharacterMoveToTarget component for Trafalgar (player) or Both
Vector3 stopPoint;
bool customTargetFound = false;
CharacterMoveToTarget[] moveTargets = GetComponentsInChildren<CharacterMoveToTarget>();
foreach (var target in moveTargets)
{
// Target is valid if it matches Trafalgar specifically or is set to Both
if (target.characterType == CharacterToInteract.Trafalgar || target.characterType == CharacterToInteract.Both)
{
stopPoint = target.GetTargetPosition();
customTargetFound = true;
// We need to wait for the player to arrive, so use a TaskCompletionSource
var tcs = new TaskCompletionSource<bool>();
// Use local functions instead of circular lambda references
void OnPlayerArrivedLocal()
{
// First remove both event handlers to prevent memory leaks
if (_playerRef != null)
{
_playerRef.OnArrivedAtTarget -= OnPlayerArrivedLocal;
_playerRef.OnMoveToCancelled -= OnPlayerMoveCancelledLocal;
}
// Then continue with the interaction flow
OnPlayerArrivedAsync().ContinueWith(_ => tcs.TrySetResult(true));
}
void OnPlayerMoveCancelledLocal()
{
// First remove both event handlers to prevent memory leaks
if (_playerRef != null)
{
_playerRef.OnArrivedAtTarget -= OnPlayerArrivedLocal;
_playerRef.OnMoveToCancelled -= OnPlayerMoveCancelledLocal;
}
// Then handle the cancellation
OnPlayerMoveCancelledAsync().ContinueWith(_ => tcs.TrySetResult(false));
}
// Unsubscribe previous handlers (if any)
_playerRef.OnArrivedAtTarget -= OnPlayerArrived;
_playerRef.OnMoveToCancelled -= OnPlayerMoveCancelled;
// Subscribe our new handlers
_playerRef.OnArrivedAtTarget += OnPlayerArrivedLocal;
_playerRef.OnMoveToCancelled += OnPlayerMoveCancelledLocal;
// Start the player movement
_playerRef.MoveToAndNotify(stopPoint);
// Await player arrival
await tcs.Task;
return;
}
}
// If no custom target was found, use the default behavior
if (!customTargetFound)
{
// Compute closest point on the interaction radius
Vector3 interactablePos = transform.position;
Vector3 playerPos = _playerRef.transform.position;
float stopDistance = characterToInteract == CharacterToInteract.Pulver
? GameManager.Instance.PlayerStopDistance
: GameManager.Instance.PlayerStopDistanceDirectInteraction;
Vector3 toPlayer = (playerPos - interactablePos).normalized;
stopPoint = interactablePos + toPlayer * stopDistance;
// Unsubscribe previous to avoid duplicate calls
_playerRef.OnArrivedAtTarget -= OnPlayerArrived;
_playerRef.OnMoveToCancelled -= OnPlayerMoveCancelled;
_playerRef.OnArrivedAtTarget += OnPlayerArrived;
_playerRef.OnMoveToCancelled += OnPlayerMoveCancelled;
_playerRef.MoveToAndNotify(stopPoint);
// We need to wait for the player to arrive, so use a TaskCompletionSource
var tcs = new TaskCompletionSource<bool>();
// Use local functions instead of circular lambda references
void OnPlayerArrivedLocal()
{
// First remove both event handlers to prevent memory leaks
if (_playerRef != null)
{
_playerRef.OnArrivedAtTarget -= OnPlayerArrivedLocal;
_playerRef.OnMoveToCancelled -= OnPlayerMoveCancelledLocal;
}
// Then continue with the interaction flow
OnPlayerArrivedAsync().ContinueWith(_ => tcs.TrySetResult(true));
}
void OnPlayerMoveCancelledLocal()
{
// First remove both event handlers to prevent memory leaks
if (_playerRef != null)
{
_playerRef.OnArrivedAtTarget -= OnPlayerArrivedLocal;
_playerRef.OnMoveToCancelled -= OnPlayerMoveCancelledLocal;
}
// Then handle the cancellation
OnPlayerMoveCancelledAsync().ContinueWith(_ => tcs.TrySetResult(false));
}
// Unsubscribe previous handlers (if any)
_playerRef.OnArrivedAtTarget -= OnPlayerArrived;
_playerRef.OnMoveToCancelled -= OnPlayerMoveCancelled;
// Subscribe our new handlers
_playerRef.OnArrivedAtTarget += OnPlayerArrivedLocal;
_playerRef.OnMoveToCancelled += OnPlayerMoveCancelledLocal;
// Start the player movement
_playerRef.MoveToAndNotify(stopPoint);
// Await player arrival
await tcs.Task;
}
}
private void OnPlayerMoveCancelled()
private async Task OnPlayerMoveCancelledAsync()
{
_interactionInProgress = false;
interactionInterrupted?.Invoke();
await DispatchEventAsync(InteractionEventType.InteractionInterrupted);
}
private void OnPlayerArrived()
private async Task OnPlayerArrivedAsync()
{
if (!_interactionInProgress)
return;
// Unsubscribe to avoid memory leaks
_playerRef.OnArrivedAtTarget -= OnPlayerArrived;
// Dispatch PlayerArrived event
await DispatchEventAsync(InteractionEventType.PlayerArrived);
// After all PlayerArrived actions complete, proceed to character interaction
await HandleCharacterInteractionAsync();
}
private async Task HandleCharacterInteractionAsync()
{
if (characterToInteract == CharacterToInteract.Pulver)
{
_followerController.OnPickupArrived -= OnFollowerArrived;
_followerController.OnPickupArrived += OnFollowerArrived;
_followerController.GoToPointAndReturn(transform.position, _playerRef.transform);
// We need to wait for the follower to arrive, so use a TaskCompletionSource
var tcs = new TaskCompletionSource<bool>();
// Create a proper local function for the event handler
void OnFollowerArrivedLocal()
{
// First remove the event handler to prevent memory leaks
if (_followerController != null)
{
_followerController.OnPickupArrived -= OnFollowerArrivedLocal;
}
// Then continue with the interaction flow
OnFollowerArrivedAsync().ContinueWith(_ => tcs.TrySetResult(true));
}
// Register our new local function handler
_followerController.OnPickupArrived += OnFollowerArrivedLocal;
// Check for a CharacterMoveToTarget component for Pulver or Both
Vector3 targetPosition = transform.position;
CharacterMoveToTarget[] moveTargets = GetComponentsInChildren<CharacterMoveToTarget>();
foreach (var target in moveTargets)
{
if (target.characterType == CharacterToInteract.Pulver || target.characterType == CharacterToInteract.Both)
{
targetPosition = target.GetTargetPosition();
break;
}
}
_followerController.GoToPointAndReturn(targetPosition, _playerRef.transform);
// Await follower arrival
await tcs.Task;
}
else if (characterToInteract == CharacterToInteract.Trafalgar)
{
BroadcastCharacterArrived();
await BroadcastCharacterArrivedAsync();
}
else if (characterToInteract == CharacterToInteract.Both)
{
// We need to wait for the follower to arrive, so use a TaskCompletionSource
var tcs = new TaskCompletionSource<bool>();
// Create a proper local function for the event handler
void OnFollowerArrivedLocal()
{
// First remove the event handler to prevent memory leaks
if (_followerController != null)
{
_followerController.OnPickupArrived -= OnFollowerArrivedLocal;
}
// Then continue with the interaction flow
OnFollowerArrivedAsync().ContinueWith(_ => tcs.TrySetResult(true));
}
// Register our new local function handler
_followerController.OnPickupArrived += OnFollowerArrivedLocal;
// Check for a CharacterMoveToTarget component for Pulver or Both
Vector3 targetPosition = transform.position;
CharacterMoveToTarget[] moveTargets = GetComponentsInChildren<CharacterMoveToTarget>();
foreach (var target in moveTargets)
{
if (target.characterType == CharacterToInteract.Pulver || target.characterType == CharacterToInteract.Both)
{
targetPosition = target.GetTargetPosition();
break;
}
}
_followerController.GoToPointAndReturn(targetPosition, _playerRef.transform);
// Await follower arrival
await tcs.Task;
}
}
private void OnFollowerArrived()
private async Task OnFollowerArrivedAsync()
{
if (!_interactionInProgress)
return;
// Unsubscribe to avoid memory leaks
_followerController.OnPickupArrived -= OnFollowerArrived;
// Dispatch FollowerArrived event
await DispatchEventAsync(InteractionEventType.InteractingCharacterArrived);
BroadcastCharacterArrived();
// After all FollowerArrived actions complete, proceed to character arrived
await BroadcastCharacterArrivedAsync();
}
private void BroadcastCharacterArrived()
// Legacy non-async method to maintain compatibility with existing code
private void OnPlayerArrived()
{
// This is now just a wrapper for the async version
_ = OnPlayerArrivedAsync();
}
// Legacy non-async method to maintain compatibility with existing code
private void OnPlayerMoveCancelled()
{
// This is now just a wrapper for the async version
_ = OnPlayerMoveCancelledAsync();
}
private async Task BroadcastCharacterArrivedAsync()
{
// Check for ObjectiveStepBehaviour and lock state
var step = GetComponent<PuzzleS.ObjectiveStepBehaviour>();
@@ -138,16 +403,24 @@ namespace Interactions
_followerController = null;
return;
}
// Dispatch CharacterArrived event
// await DispatchEventAsync(InteractionEventType.InteractingCharacterArrived);
// Broadcast appropriate event
characterArrived?.Invoke();
// Reset variables for next time
_interactionInProgress = false;
_playerRef = null;
_followerController = null;
}
private void OnInteractionComplete(bool success)
private async void OnInteractionComplete(bool success)
{
// Dispatch InteractionComplete event
await DispatchEventAsync(InteractionEventType.InteractionComplete);
if (success)
{
if (isOneTime)

View File

@@ -0,0 +1,91 @@
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using System.Threading.Tasks;
using Input;
namespace Interactions
{
/// <summary>
/// Base class for all interaction action components
/// These components respond to interaction events and can control the interaction flow
/// </summary>
public abstract class InteractionActionBase : MonoBehaviour
{
[Tooltip("Which interaction events this action should respond to")]
public List<InteractionEventType> respondToEvents = new List<InteractionEventType>();
[Tooltip("Whether the interaction flow should wait for this action to complete")]
public bool pauseInteractionFlow = true;
protected Interactable parentInteractable;
protected virtual void Awake()
{
// Get the parent interactable component
parentInteractable = GetComponentInParent<Interactable>();
if (parentInteractable == null)
{
Debug.LogError($"[{GetType().Name}] Cannot find parent Interactable component!");
enabled = false;
return;
}
}
protected virtual void OnEnable()
{
if (parentInteractable != null)
{
parentInteractable.RegisterAction(this);
}
}
protected virtual void OnDisable()
{
if (parentInteractable != null)
{
parentInteractable.UnregisterAction(this);
}
}
/// <summary>
/// Called when an interaction event occurs that this action is registered for
/// </summary>
/// <param name="eventType">The type of event that occurred</param>
/// <returns>A task that completes when the action is finished, or null if action won't execute</returns>
public Task<bool> OnInteractionEvent(InteractionEventType eventType, PlayerTouchController player, FollowerController follower)
{
if (respondToEvents.Contains(eventType) && ShouldExecute(eventType, player, follower))
{
if (pauseInteractionFlow)
{
return ExecuteAsync(eventType, player, follower);
}
else
{
// If we don't need to pause the flow, execute in the background
// and return a completed task
_ = ExecuteAsync(eventType, player, follower);
return Task.FromResult(false);
}
}
return null;
}
/// <summary>
/// Execute the action for the given event asynchronously
/// </summary>
protected abstract Task<bool> ExecuteAsync(InteractionEventType eventType, PlayerTouchController player, FollowerController follower);
/// <summary>
/// Called to determine if this action should execute for the given event
/// Override this to add additional conditions for execution
/// </summary>
protected virtual bool ShouldExecute(InteractionEventType eventType, PlayerTouchController player, FollowerController follower)
{
return true;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5cf351d32dac4169a9db20609727a70f
timeCreated: 1759746705

View File

@@ -0,0 +1,16 @@
using System;
namespace Interactions
{
/// <summary>
/// Defines the different types of events that can occur during an interaction
/// </summary>
public enum InteractionEventType
{
InteractionStarted,
PlayerArrived,
InteractingCharacterArrived,
InteractionComplete,
InteractionInterrupted
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 78684d31bd4d4636834a494c7cb74f48
timeCreated: 1759746690

View File

@@ -0,0 +1,241 @@
using System;
using UnityEngine;
using UnityEngine.Playables;
using System.Linq;
using System.Threading.Tasks;
using Input;
namespace Interactions
{
/// <summary>
/// Component that plays timeline animations in response to interaction events
/// </summary>
[RequireComponent(typeof(PlayableDirector))]
public class InteractionTimelineAction : InteractionActionBase
{
[System.Serializable]
public class TimelineEventMapping
{
public InteractionEventType eventType;
public PlayableAsset[] timelines;
[Tooltip("Whether to bind the player character to the track named 'Player'")]
public bool bindPlayerCharacter = false;
[Tooltip("Whether to bind the follower character to the track named 'Pulver'")]
public bool bindPulverCharacter = false;
[Tooltip("Custom track name for player character binding")]
public string playerTrackName = "Player";
[Tooltip("Custom track name for follower character binding")]
public string pulverTrackName = "Pulver";
[Tooltip("Time in seconds before the timeline is automatically completed (safety feature)")]
public float timeoutSeconds = 30f;
[Tooltip("Whether to loop the last timeline in the sequence")]
public bool loopLast = false;
[Tooltip("Whether to loop through all timelines in the sequence")]
public bool loopAll = false;
// Helper property to check if we have valid timelines
public bool HasValidTimelines => timelines != null && timelines.Length > 0 && timelines[0] != null;
}
[Header("Timeline Configuration")] [SerializeField]
private PlayableDirector playableDirector;
[SerializeField] private TimelineEventMapping[] timelineMappings;
private TaskCompletionSource<bool> _currentPlaybackTCS;
private int _currentTimelineIndex = 0;
private TimelineEventMapping _currentMapping = null;
protected override void Awake()
{
base.Awake();
if (playableDirector == null)
{
playableDirector = GetComponent<PlayableDirector>();
}
if (playableDirector == null)
{
Debug.LogError("[InteractionTimelineAction] PlayableDirector component is missing!");
enabled = false;
return;
}
// Subscribe to the director's stopped event
playableDirector.stopped += OnPlayableDirectorStopped;
}
private void OnDestroy()
{
if (playableDirector != null)
{
playableDirector.stopped -= OnPlayableDirectorStopped;
}
}
protected override async Task<bool> ExecuteAsync(InteractionEventType eventType, PlayerTouchController player,
FollowerController follower)
{
// Find the timeline for this event type
TimelineEventMapping mapping = Array.Find(timelineMappings, m => m.eventType == eventType);
if (mapping == null || !mapping.HasValidTimelines)
{
// No timeline configured for this event
return true;
}
_currentMapping = mapping;
_currentTimelineIndex = 0;
return await PlayTimelineSequence(player, follower);
}
private async Task<bool> PlayTimelineSequence(PlayerTouchController player, FollowerController follower)
{
if (_currentMapping == null || !_currentMapping.HasValidTimelines)
{
return true;
}
// Play the current timeline in the sequence
bool result = await PlaySingleTimeline(_currentMapping.timelines[_currentTimelineIndex], _currentMapping, player, follower);
// Return false if the playback failed
if (!result)
{
return false;
}
// Increment the timeline index for next playback
_currentTimelineIndex++;
// Check if we've reached the end of the sequence
if (_currentTimelineIndex >= _currentMapping.timelines.Length)
{
// If loop all is enabled, start over
if (_currentMapping.loopAll)
{
_currentTimelineIndex = 0;
// Don't continue automatically, wait for next interaction
return true;
}
// If loop last is enabled, replay the last timeline
else if (_currentMapping.loopLast)
{
_currentTimelineIndex = _currentMapping.timelines.Length - 1;
// Don't continue automatically, wait for next interaction
return true;
}
// Otherwise, we're done with the sequence
else
{
_currentTimelineIndex = 0;
_currentMapping = null;
return true;
}
}
// If we have more timelines in the sequence, we're done for now
// Next interaction will pick up where we left off
return true;
}
private async Task<bool> PlaySingleTimeline(PlayableAsset timelineAsset, TimelineEventMapping mapping,
PlayerTouchController player, FollowerController follower)
{
if (timelineAsset == null)
{
Debug.LogWarning("[InteractionTimelineAction] Timeline asset is null");
return true;
}
// Set the timeline asset
playableDirector.playableAsset = timelineAsset;
// Bind characters if needed
if (mapping.bindPlayerCharacter && player != null)
{
try
{
var trackOutput = playableDirector.playableAsset.outputs.FirstOrDefault(o => o.streamName == mapping.playerTrackName);
if (trackOutput.sourceObject != null)
{
playableDirector.SetGenericBinding(trackOutput.sourceObject, player.gameObject);
}
else
{
Debug.LogWarning($"[InteractionTimelineAction] Could not find track named '{mapping.playerTrackName}' for player binding");
}
}
catch (Exception ex)
{
Debug.LogError($"[InteractionTimelineAction] Error binding player to timeline: {ex.Message}");
}
}
if (mapping.bindPulverCharacter && follower != null)
{
try
{
var trackOutput = playableDirector.playableAsset.outputs.FirstOrDefault(o => o.streamName == mapping.pulverTrackName);
if (trackOutput.sourceObject != null)
{
playableDirector.SetGenericBinding(trackOutput.sourceObject, follower.gameObject);
}
else
{
Debug.LogWarning($"[InteractionTimelineAction] Could not find track named '{mapping.pulverTrackName}' for follower binding");
}
}
catch (Exception ex)
{
Debug.LogError($"[InteractionTimelineAction] Error binding follower to timeline: {ex.Message}");
}
}
// Create a task completion source to await the timeline completion
_currentPlaybackTCS = new TaskCompletionSource<bool>();
// Play the timeline
playableDirector.Play();
// Start a timeout coroutine for safety using the mapping's timeout
StartCoroutine(TimeoutCoroutine(mapping.timeoutSeconds));
// Wait for the timeline to complete (or timeout)
bool result = await _currentPlaybackTCS.Task;
_currentPlaybackTCS = null;
return result;
}
private void OnPlayableDirectorStopped(PlayableDirector director)
{
if (director == playableDirector && _currentPlaybackTCS != null)
{
_currentPlaybackTCS.TrySetResult(true);
}
}
private System.Collections.IEnumerator TimeoutCoroutine(float timeoutDuration)
{
yield return new WaitForSeconds(timeoutDuration);
// If the TCS still exists after timeout, complete it with failure
if (_currentPlaybackTCS != null)
{
Debug.LogWarning($"[InteractionTimelineAction] Timeline playback timed out after {timeoutDuration} seconds");
_currentPlaybackTCS.TrySetResult(false);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 42e77a0c97604b6eb7674e58726c831a
timeCreated: 1759746720