public static MonoFSM <T> Init(MonoBehaviour component, T startState) { var engine = component.GetComponent <MonoFSMRunner>(); if (engine == null) { engine = component.gameObject.AddComponent <MonoFSMRunner>(); } return(engine.Initialize <T>(component, startState)); }
public MonoFSM(MonoFSMRunner engine, MonoBehaviour component) { this.engine = engine; this.component = component; var values = Enum.GetValues(typeof(T)); if (values.Length < 1) { throw new ArgumentException("必须至少定义一个枚举的,亲!"); } stateLookup = new Dictionary <object, StateMapping>(); for (int i = 0; i < values.Length; i++) { var mapping = new StateMapping((Enum)values.GetValue(i)); stateLookup.Add(mapping.state, mapping); } var methods = component.GetType().GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic); var separator = "_".ToCharArray(); for (int i = 0; i < methods.Length; i++) { if (methods[i].GetCustomAttributes(typeof(CompilerGeneratedAttribute), true).Length != 0) { continue; } var names = methods[i].Name.Split(separator); if (names.Length <= 1) { continue; } Enum key; try { key = (Enum)Enum.Parse(typeof(T), names[0]); } catch (ArgumentException) { continue; } var targetState = stateLookup[key]; switch (names[1]) { case "Enter": if (methods[i].ReturnType == typeof(IEnumerator)) { targetState.HasEnterRoutine = true; targetState.EnterRoutine = CreateDelegate <Func <IEnumerator> >(methods[i], component); } else { targetState.HasEnterRoutine = false; targetState.EnterCall = CreateDelegate <Action>(methods[i], component); } break; case "Exit": if (methods[i].ReturnType == typeof(IEnumerator)) { targetState.HasExitRoutine = true; targetState.ExitRoutine = CreateDelegate <Func <IEnumerator> >(methods[i], component); } else { targetState.HasExitRoutine = false; targetState.ExitCall = CreateDelegate <Action>(methods[i], component); } break; case "Finally": targetState.Finally = CreateDelegate <Action>(methods[i], component); break; case "Update": targetState.Update = CreateDelegate <Action>(methods[i], component); break; case "LateUpdate": targetState.LateUpdate = CreateDelegate <Action>(methods[i], component); break; case "FixedUpdate": targetState.FixedUpdate = CreateDelegate <Action>(methods[i], component); break; case "OnCollisionEnter": targetState.OnCollisionEnter = CreateDelegate <Action <Collision> >(methods[i], component); break; } } currentState = new StateMapping(null); }