void Init(){ // refactored this because Awake could be called after the first ExpectEvents call, wiping out the settings if (initialized) return; initialized = true; if(target == null && transform.parent != null ) target = transform.parent.gameObject; if ( target != null ) { am = target.GetComponent<AnimationManager>(); tc = target.GetComponent<TaskCharacter>(); } skippedEvents = new List<string>(); expectedEvents = new AnimEventList(); expectedEvents.events = new List<AnimationEvent>(); receivedEvents = new List<AnimationEvent>(); // MatchingLists = new List<AnimEventList>() ; if (animEventList == null){ Serializer<List<AnimEventList>> serializer = new Serializer<List<AnimEventList>>(); string pathname = "XML/AnimEventList"; animEventList = serializer.Load(pathname); // CheckForDuplicateClips(); // there are a lot of duplicates, we are dealing with it. } }
public void ExpectEventsFor(string clipname){ Init (); prevClipName = setClipName; setClipName = clipname; if (expectedEvents == null){ expectedEvents = new AnimEventList(); expectedEvents.events = new List<AnimationEvent>(); } // here's where we check for any unfired events, but not for looping mode clips if (animation[expectedEvents.clipName] != null && animation[expectedEvents.clipName].wrapMode != WrapMode.Loop) { foreach (AnimationEvent eve in expectedEvents.events) { if (eve.time < animation [prevClipName].time) { // the event's time in the clip has passed, should have fired Debug.LogError (Time.time + target.name + ": AnimationEvent " + eve.functionName + ":" + eve.time + " FAILED TO TRIGGER for " + prevClipName + ":" + animation [prevClipName].time); string message = Time.time + target.name + ": AnimationEvent " + ":" + eve.time + eve.functionName + " FAILED TO TRIGGER for " + prevClipName + ":" + animation [prevClipName].time; skippedEvents.Add (message); } } } expectedEvents.events.Clear(); receivedEvents.Clear(); bool found = false; string eventnames = "-"; foreach (AnimEventList list in animEventList){ // this next test assumes that the no event clips, without owners listed, are checked last, thus act as defaults if no if (list.clipName == clipname && (list.owners == null || list.owners.Contains(target.name))){ found = true; expectedEvents.clipName = clipname; foreach (AnimationEvent e in list.events){ expectedEvents.events.Add(e); // do we need to make a copy of 'e' ? i dont think so eventnames += e.functionName; // only set a failsafe for non-looping clips if (animation[expectedEvents.clipName].wrapMode != WrapMode.Loop) StartCoroutine(StartFailsafeFor(e)); // start a time based co routine to be sure this triggers. } #if DEBUG_ANIM_EVENTS // if (list.owners == null) // Debug.LogWarning(target.name+" using default no-event clip for "+clipname); #endif break; } } // Debug.LogError (Time.time+": "+target.name+" starting clip "+clipname+" has events "+expectedEvents.events.Count+eventnames); if (!found) Debug.LogError(target.name+" found no event list for clip "+clipname); //if (clipname != expectedEvents.clipName) Debug.LogError("HOW COULD THIS HAPPEN???"); // awake was getting called after ExpectEvent //Debug.LogError(target.name+" expectEventsFor ["+clipname+"] found ["+expectedEvents.clipName+"]"); }
static void DoExport(bool makeSubmeshes) { List<AnimEventList> clipLists; List<AnimationClip> processedClips; // if (Selection.gameObjects.Length == 0) // { // Debug.Log("Didn't Export Anything!"); // return; // } clipLists = new List<AnimEventList>(); processedClips = new List<AnimationClip>(); List<AnimationClip> zeroEventClips = new List<AnimationClip>(); // collect all the animation messenger components... AnimationMessenger[] messengers = FindObjectsOfType<AnimationMessenger> (); // in the scene //foreach (GameObject obj in Selection.gameObjects){ foreach (AnimationMessenger mess in messengers){ GameObject obj = mess.gameObject; GameObject target = FindTarget(mess); if (obj.animation != null){ // be sure we have a foreach (AnimationState state in obj.animation){ if (!processedClips.Contains (state.clip)){ AnimationEvent[] evs = AnimationUtility.GetAnimationEvents(state.clip); if (evs.Length > 0){ processedClips.Add(state.clip); AnimEventList evList = new AnimEventList(); evList.events = new List<AnimationEvent>(); evList.clipName = state.clip.name; evList.clip = state.clip; evList.owners = target.name; // start with the first owner foreach (AnimationEvent ev in evs){ evList.events.Add (ev); } Debug.Log (evs.Length+" events found on clip "+state.clip.name+" of "+target.name); clipLists.Add (evList); } else { if (!zeroEventClips.Contains (state.clip)){ Debug.LogWarning(state.clip.name+" has NO animation Events"); zeroEventClips.Add(state.clip); } } } else{ // add this character as an owner of the clip foreach (AnimEventList checkList in clipLists) // we might not be able to access this while in use... if (checkList.clip == state.clip){ checkList.owners += " "+ target.name; break; } } } } } // add all the zero event clips at the end so we can find them in the xml foreach (AnimationClip clip in zeroEventClips){ AnimEventList evList = new AnimEventList(); evList.events = new List<AnimationEvent>(); evList.clipName = clip.name; //evList.clip = clip; clipLists.Add (evList); } // we may have to null out the 'clip' elements for serialization foreach (AnimEventList list in clipLists) list.clip = null; // there's really no useful info here... // now lets try to serialize them XmlSerializer serializer = new XmlSerializer(typeof(List<AnimEventList>)); FileStream stream = new FileStream("AnimEventList.xml", FileMode.Create); serializer.Serialize(stream, clipLists); stream.Close(); Debug.Log (clipLists.Count+" Animations With Events serialized"); }