Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@ public override void OnInspectorGUI()
GUILayout.EndHorizontal();

GUILayout.Space(10); // Add some more spacing

EditorGUILayout.PropertyField(serializedObject.FindProperty("initializeOnAwake"), new GUIContent("Initialize on Awake"));

GUILayout.Space(5); // Add some more spacing

if (animator != null && animator.runtimeAnimatorController != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ public class AnimationEventHandler : MonoBehaviour
/// List of AnimationEventData instances representing animation events to manage.
public List<AnimationEventData> animationEvents = new List<AnimationEventData>();

public bool initializeOnAwake = true;

private void Awake()
{
animator = GetComponent<Animator>();
}

private void Start()
{

if(!initializeOnAwake) return;

AddEvents();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using UnityEngine;

namespace EasyAnimationEvent
{
public class AnimationEventUtils
{
public static string ConstructKey(AnimationClip clip, float time) => $"{clip.name}_{time}";
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 15 additions & 14 deletions Assets/Easy Animation Event/Source/Runtime/EventReceiver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

using System;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;

namespace EasyAnimationEvent
Expand All @@ -16,15 +17,15 @@ namespace EasyAnimationEvent
public class EventReceiver : MonoBehaviour
{
// Dictionary storing callbacks and their names for each timeline position.
private readonly Dictionary<float, List<(Action callback, string name)>> CallbacksPoll = new Dictionary<float, List<(Action callback, string name)>>();
private readonly Dictionary<string, List<(Action callback, string name)>> CallbacksPoll = new Dictionary<string, List<(Action callback, string name)>>();

/// <summary>
/// Registers a callback to be invoked at a specific timeline position.
/// </summary>
/// <param name="position">The timeline position at which the callback should be invoked.</param>
/// <param name="callback">The callback to register.</param>
/// <param name="name">The name of the callback.</param>
public void RegisterEvent(float position, Action callback, string name)
public void RegisterEvent(string key, Action callback, string name)
{
if (callback == null)
{
Expand All @@ -37,13 +38,13 @@ public void RegisterEvent(float position, Action callback, string name)
Debug.LogWarning("Attempted to register a callback with a null or empty name.");
return;
}

if (!CallbacksPoll.ContainsKey(position))
if (!CallbacksPoll.ContainsKey(key))
{
CallbacksPoll[position] = new List<(Action callback, string name)>();
CallbacksPoll[key] = new List<(Action callback, string name)>();
}

CallbacksPoll[position].Add((callback, name));
CallbacksPoll[key].Add((callback, name));
}

/// <summary>
Expand All @@ -52,17 +53,17 @@ public void RegisterEvent(float position, Action callback, string name)
/// <param name="position">The timeline position from which the callback should be unregistered.</param>
/// <param name="name">The name of the callback to unregister.</param>
/// <returns>True if it was the last callback for the position and the position was removed; otherwise, false.</returns>
public bool UnregisterEvent(float position, string name)
public bool UnregisterEvent(string key)
{
if (string.IsNullOrEmpty(name))
if (string.IsNullOrEmpty(key))
{
Debug.LogWarning("Attempted to unregister a callback with a null or empty name.");
return false;
}

if (!CallbacksPoll.TryGetValue(position, out var callbacks))
if (!CallbacksPoll.TryGetValue(key, out var callbacks))
{
Debug.LogWarning($"Attempted to unregister a callback not registered at position {position}.");
Debug.LogWarning($"Attempted to unregister a callback not registered at key {key}.");
return false;
}

Expand All @@ -78,7 +79,7 @@ public bool UnregisterEvent(float position, string name)

if (callbacks.Count == 0)
{
CallbacksPoll.Remove(position);
CallbacksPoll.Remove(key);
return true;
}

Expand All @@ -89,11 +90,11 @@ public bool UnregisterEvent(float position, string name)
/// Invoked by Unity's animation system to trigger callbacks at a specific timeline position.
/// </summary>
/// <param name="position">The timeline position at which to trigger callbacks.</param>
private void OnEvent(float position)
private void OnEvent(string key)
{
if (!CallbacksPoll.TryGetValue(position, out var callbacks))
if (!CallbacksPoll.TryGetValue(key, out var callbacks))
{
Debug.LogWarning($"No callbacks registered for timeline position {position}.");
Debug.LogWarning($"No callbacks registered for timeline position {key}.");
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ private static void BindOrUnbindEvent(this AnimationClip clip, GameObject animEv
}

// Register the callback at the specified timeline position
eventReceiver.RegisterEvent(position, callback, methodName);
eventReceiver.RegisterEvent(AnimationEventUtils.ConstructKey(clip, position), callback, methodName);

// Add an AnimationEvent to the AnimationClip if it doesn't already exist
clip.AddEventIfNotExists(OnEvent, position, position);
Expand All @@ -98,7 +98,7 @@ private static void BindOrUnbindEvent(this AnimationClip clip, GameObject animEv
}

// Unregister the callback from the EventReceiver
var lastEventForPositionRemoved = eventReceiver.UnregisterEvent(position, methodName);
var lastEventForPositionRemoved = eventReceiver.UnregisterEvent(AnimationEventUtils.ConstructKey(clip, position));
if (lastEventForPositionRemoved)
{
// Remove the AnimationEvent from the AnimationClip if it was the last event at that position
Expand All @@ -116,16 +116,18 @@ private static void BindOrUnbindEvent(this AnimationClip clip, GameObject animEv
/// <param name="time">The time in the animation clip timeline associated with the event.</param>
private static void AddEventIfNotExists(this AnimationClip clip, string methodName, float floatParameter, float time)
{
var key = AnimationEventUtils.ConstructKey(clip, floatParameter);

var clipAnimationEvents = clip.events;
var animationEvent = Array.Find(clipAnimationEvents,
e => e.functionName == methodName && e.floatParameter == floatParameter && e.time == time);
e => e.functionName == methodName && e.stringParameter == key && e.time == time);

if (animationEvent == null)
{
// Create a new AnimationEvent and add it to the AnimationClip
animationEvent = new AnimationEvent();
animationEvent.functionName = methodName;
animationEvent.floatParameter = floatParameter;
animationEvent.stringParameter = key;
animationEvent.time = time;
clip.AddEvent(animationEvent);
}
Expand Down