Cache GetComponent Calls
When using Fsm Variables you should assume that their value could change over the lifetime of the Action. In a MonoBehaviour you might cache a Component reference in Start(). In an Action this is risky, since the target might change and the Component is no longer the one you want.
Instead use this pattern to cache the component whenever the target GameObject changes:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: |
public class MyAction: FsmStateAction { // public action parameters here public FsmGameObject gameObject; public bool everyFrame; // private caches private GameObject cachedGO; private MyComponent cachedComponent; public override void OnEnter() { DoMyAction(); if (!everyFrame) Finish(); } public override void OnUpdate() { DoMyAction(); } void DoMyAction() { if (cachedGO != gameObject.Value) { cachedGO = gameObject.Value; cachedComponent = cachedGO.GetComponent<MyComponent>(); } // Use cachedComponent every frame instead of GetComponent // ... } |
Note: That snippet also shows a useful pattern to implement the Every Frame option. Put your action in a separate method that can be called from both OnEnter and OnUpdate.
Use Action Subclasses for Related Actions
If you have a set of actions with shared features it can be useful to create a subclass of FsmStateAction with those shared features. Then each action in the set can derive from that subclass instead of FsmStateAction. See the GUILayout actions as an example.
Make Sure Your Action Class is Public
If you don't see your custom action in the Action Browser, make sure it is public!