Pharan wroteSo for attachments, if there are no keys, it returns to setup pose. If there are keys, it uses those attachment values. This results in animations always looking as they do in Spine editor.
Yeah, I am aware of this, and it makes perfect sense!
My current use case is simple so that I can go for the second solution. I am thinking of an idea - can I go through all head timelines and instead of head keys create events that will trigger the skeletonAnimation.Skeleton.SetAttachment() method?
Something like this should work:
var newEvent = new Event(time, new EventData("ChangeHead");
newEvent.String = "Happy";
eventTimeline.SetFrame(frameIndex, newEvent);
I am not sure what is the difference between the frameIndex for the SetFrame method and the time for Event constructor?
Does the setFrame method work just for modifying existing frames? What if I want to add a new key? I see I can create a new timeline with the specified number of keys, so the solution is to copy all previous keys to the newly created timeline, delete the old timeline and add the new one?
OR - can I just create new EventTimeline and ignore there is one existing already? Will the runtime handle two EventTimelines?
public static void CopyHeadKeysAsEvents(this Animation animation, int headSlotIndex)
{
for (int i = 0; i < animation.Timelines.Count; i++)
{
var attachmentTimeline = animation.Timelines.Items[i] as AttachmentTimeline;
// Select AttachmentTimeline with head slot
if (attachmentTimeline != null && attachmentTimeline.SlotIndex == headSlotIndex && attachmentTimeline.Frames.Length > 0)
{
var eventTimeline = animation.GetEventTimeline(attachmentTimeline.Frames.Length);
for (int j = 0; j < attachmentTimeline.Frames.Length; j++)
{
// For every frame, create event in new EventTimeline
var newEvent = new Event(attachmentTimeline.Frames[j], new EventData(ChangeHeadEvent));
newEvent.String = attachmentTimeline.AttachmentNames[j];
eventTimeline.SetFrame(j, newEvent);
}
// Remove original head AttachmentTimeline
animation.Timelines.RemoveAt(i);
return;
}
}
}
public static EventTimeline GetEventTimeline(this Animation animation, int framesCount)
{
// Get current existing EventTimeline, is it necessary?
/*var timeline = animation.Timelines.FirstOrDefault(t => t is EventTimeline) as EventTimeline;
if (timeline != null)
return timeline;*/
var newTimeline = new EventTimeline(framesCount);
animation.Timelines.Add(newTimeline);
return newTimeline;
}
It works! I only need to know the answer to my last question. Is it ok to create a completely new EventTimeline event if there might be EventTimeline already?