protected virtual void Start() { if(sequencer != null) { //Sequencer.StateInstance mStateInstance = new SequencerInstance(); sequencer.Start(this, mStateInstance, mStartState); } }
protected virtual void SequenceChangeState(string state) { //stop previous routine if(mStateInstance != null) { mStateInstance.terminate = true; } //create a new one mStateInstance = new SequencerInstance(); sequencer.Start(this, mStateInstance, state); }
public void Start(MonoBehaviour behaviour, SequencerInstance instance, string stateName) { if(stateName == null) { stateName = sequenceDefaultState; } mCurState = stateName; if(!string.IsNullOrEmpty(stateName)) { if(mSequences != null) { Sequencer seq; if(mSequences.TryGetValue(stateName, out seq)) { behaviour.StartCoroutine(seq.Go(instance, behaviour)); } else { Debug.LogError("State not found: "+stateName, behaviour); } } } }
public IEnumerator Go(SequencerInstance instance, MonoBehaviour behaviour) { //start off with given 'toPhase' in instance or start phase string toPhase = !string.IsNullOrEmpty(instance.toPhase) ? instance.toPhase : mStartPhase; while(!instance.terminate) { //stay if(instance.pause) { yield return new WaitForFixedUpdate(); continue; } Phase curPhase = null; //get phase if(string.IsNullOrEmpty(toPhase) || !mPhases.TryGetValue(toPhase, out curPhase)) { //go through evals foreach(SequencerEval eval in mEvals) { //check then try to fill phase data if(eval.Check(behaviour, instance) && !string.IsNullOrEmpty(eval.phase) && mPhases.TryGetValue(eval.phase, out curPhase)) { break; } } } else { toPhase = null; } SequencerAction[] actions = curPhase != null ? curPhase.actions : null; if(actions != null) { int actionInd = 0; int len = actions.Length; while(!instance.terminate && actionInd < len) { SequencerAction action = actions[actionInd]; if(action.delay > 0) { yield return new WaitForSeconds(action.delay); } //ensure nothing is started when we pause or terminate early while(!instance.terminate && instance.pause) { yield return new WaitForFixedUpdate(); } if(instance.terminate) { break; } instance.startTime = Time.time; action.Start(behaviour, instance); while(!instance.terminate && !action.Update(behaviour, instance)) { yield return new WaitForFixedUpdate(); //ensure we wait until unpaused before updating again //warning: state from start might change......... //look at this comment if shit hits the fan in game //however...we don't want finish or update to happen when we //rely on certain state to be consistent outside... while(!instance.terminate && instance.pause) { yield return new WaitForFixedUpdate(); continue; } } action.Finish(behaviour, instance); //check to see if we want to go to next phase if(!string.IsNullOrEmpty(instance.toPhase)) { toPhase = instance.toPhase; break; } //just end current phase else if(instance.breakPhase) { break; } //continue else { actionInd++; //loop back or change to a new phase? if(actionInd == len && curPhase.loop) { actionInd = 0; yield return new WaitForFixedUpdate(); } } } //reset action specific instance params instance.toPhase = null; instance.breakPhase = false; } //go back to evaluate again yield return new WaitForFixedUpdate(); } yield break; }
public bool Check(MonoBehaviour behaviour, SequencerInstance instance) { foreach(SequencerCriteria criteria in criterias) { if(criteria.Evaluate(behaviour, instance)) { return true; } } return false; }
//implements public abstract bool Evaluate(MonoBehaviour behaviour, SequencerInstance instance);
protected virtual void OnDestroy() { mStateInstance = null; }
public override void Start(MonoBehaviour behaviour, SequencerInstance instance) { behaviour.SendMessage("SequenceChangeState", state, SendMessageOptions.RequireReceiver); }
public override void Finish(MonoBehaviour behaviour, SequencerInstance instance) { instance.toPhase = phase; }
/// <summary> /// Periodic update, return true if done. /// </summary> public virtual bool Update(MonoBehaviour behaviour, SequencerInstance instance) { return true; }
//store any non-readonly fields to given behaviour, don't put them here, store them in behaviour //these sequence actions can be shared by different behaviours //can set states dependent from outside here public virtual void Start(MonoBehaviour behaviour, SequencerInstance instance) { }
//do clean ups here, don't set any states dependent from outside public virtual void Finish(MonoBehaviour behaviour, SequencerInstance instance) { }