I want to use an EditorWindow to create animation curves that will activate my hitboxes at the correct time.
When adding manually a hitbox in my animation clip. I can see its type among other things: UnityEngine.GameObject

So I coded this:
EditorCurveBinding bind = new EditorCurveBinding();
bind.type = typeof(UnityEngine.GameObject);
bind.propertyName = "m_IsActive";
bind.path = "Hitboxes/" + hitbox.name;
var keys = new List<ObjectReferenceKeyframe>();
var keyOn = new ObjectReferenceKeyframe();
keyOn.value = hitbox.gameObject;
keyOn.time = 0f;
keys.Add(keyOn);
AnimationUtility.SetObjectReferenceCurve(anim, bind, keys.ToArray());
I get the following error because of AnimationUtility.SetObjectReferenceCurve:
“Can’t assign curve because the type does not inherit from component”. (Imgur: The magic of the Internet)
Indeed, typeof(GameObject) doesn’t inherit from Component, but what can I do to make this work? Logically this should be possible since it can be done manually.
I found the solution:
private void AddAnimationCurveAccordingToHitboxNames()
{
var spriteBind = new EditorCurveBinding();
spriteBind.type = typeof(SpriteRenderer);
spriteBind.propertyName = "m_Sprite";
foreach (var hitbox in Hitboxes)
{
var goBinding = new EditorCurveBinding();
goBinding.type = typeof(GameObject);
goBinding.propertyName = "m_IsActive";
goBinding.path = "Hitboxes/" + hitbox.name;
foreach (var anim in AnimationClips)
{
var frameTime = 1 / anim.frameRate;
var sprites = AnimationUtility.GetObjectReferenceCurve(anim, spriteBind);
// find the sprites that are named correctly and their time
foreach (var s in sprites)
{
var val = s.value;
var time = s.time;
var spriteName = FindNameWithoutTagWithoutVersion(val.name, true);
// TODO: This only works if there's 1 same sprite name per animation? Do we care?
// TODO: What if the hitbox is the last frame, it doesn't get deactivated
if (spriteName == hitbox.name)
{
var curve = new AnimationCurve();
var keyBefore = new Keyframe();
keyBefore.value = 0;
keyBefore.time = time - frameTime;
var keyAfter = new Keyframe();
keyAfter.value = 0;
keyAfter.time = time + frameTime;
var keyOn = new Keyframe();
keyOn.value = 1;
keyOn.time = time;
curve.AddKey(keyBefore);
curve.AddKey(keyOn);
curve.AddKey(keyAfter);
AnimationUtility.SetEditorCurve(anim, goBinding, curve);
}
}
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
}