├── .gitattributes ├── .gitignore ├── LICENSE.md ├── README.md ├── StateMachine ├── .gitignore ├── Assets │ ├── MonsterLove.meta │ └── MonsterLove │ │ ├── Runtime.meta │ │ ├── Runtime │ │ ├── Drivers.meta │ │ ├── Drivers │ │ │ ├── StateDriverRunner.cs │ │ │ ├── StateDriverRunner.cs.meta │ │ │ ├── StateDriverUnity.cs │ │ │ └── StateDriverUnity.cs.meta │ │ ├── Events.meta │ │ ├── Events │ │ │ ├── StateEvent.cs │ │ │ └── StateEvent.cs.meta │ │ ├── MonsterLove.StateMachine.Runtime.asmdef │ │ ├── MonsterLove.StateMachine.Runtime.asmdef.meta │ │ ├── StateMachine.cs │ │ ├── StateMachine.cs.meta │ │ ├── StateMachineRunner.cs │ │ ├── StateMachineRunner.cs.meta │ │ ├── StateMapping.cs │ │ └── StateMapping.cs.meta │ │ ├── Samples.meta │ │ ├── Samples │ │ ├── Prefabs.meta │ │ ├── Prefabs │ │ │ ├── Item.prefab │ │ │ └── Item.prefab.meta │ │ ├── Scripts.meta │ │ ├── Scripts │ │ │ ├── ColorChanger.cs │ │ │ ├── ColorChanger.cs.meta │ │ │ ├── ExampleAdvanced.cs │ │ │ ├── ExampleAdvanced.cs.meta │ │ │ ├── ExampleBasic.cs │ │ │ ├── ExampleBasic.cs.meta │ │ │ ├── Item.cs │ │ │ ├── Item.cs.meta │ │ │ ├── MonsterLove.StateMachine.Samples.asmdef │ │ │ ├── MonsterLove.StateMachine.Samples.asmdef.meta │ │ │ ├── Perf.meta │ │ │ └── Perf │ │ │ │ ├── StressTest.cs │ │ │ │ └── StressTest.cs.meta │ │ ├── StateMachine_Advanced.unity │ │ ├── StateMachine_Advanced.unity.meta │ │ ├── StateMachine_Basic.unity │ │ ├── StateMachine_Basic.unity.meta │ │ ├── StressTest.unity │ │ └── StressTest.unity.meta │ │ ├── Tests.meta │ │ └── Tests │ │ ├── Editor.meta │ │ ├── Editor │ │ ├── MonsterLove.StateMachine.Tests.Editor.asmdef │ │ ├── MonsterLove.StateMachine.Tests.Editor.asmdef.meta │ │ ├── TestBasicTransitions.cs │ │ ├── TestBasicTransitions.cs.meta │ │ ├── TestCachedDriver.cs │ │ ├── TestCachedDriver.cs.meta │ │ ├── TestCustomDriver.cs │ │ ├── TestCustomDriver.cs.meta │ │ ├── TestDerivedFromSuperClass.cs │ │ ├── TestDerivedFromSuperClass.cs.meta │ │ ├── TestDisabledComponent.cs │ │ ├── TestDisabledComponent.cs.meta │ │ ├── TestDriverLifecycle.cs │ │ ├── TestDriverLifecycle.cs.meta │ │ ├── TestEmptyDriver.cs │ │ ├── TestEmptyDriver.cs.meta │ │ ├── TestInheritedDriver.cs │ │ ├── TestInheritedDriver.cs.meta │ │ ├── TestMultipleSubscribers.cs │ │ ├── TestMultipleSubscribers.cs.meta │ │ ├── TestNonStandardEnums.cs │ │ ├── TestNonStandardEnums.cs.meta │ │ ├── TestStateClassTypesMismatchDriver.cs │ │ ├── TestStateClassTypesMismatchDriver.cs.meta │ │ ├── TestStateEngineInitialization.cs │ │ └── TestStateEngineInitialization.cs.meta │ │ ├── Runtime.meta │ │ └── Runtime │ │ ├── ClassDerivedFromSuperClass.cs │ │ ├── ClassDerivedFromSuperClass.cs.meta │ │ ├── ClassWithBasicStates.cs │ │ ├── ClassWithBasicStates.cs.meta │ │ ├── MonsterLove.StateMachine.Tests.Runtime.asmdef │ │ ├── MonsterLove.StateMachine.Tests.Runtime.asmdef.meta │ │ ├── TestChangeAsyncCustomDriver.cs │ │ ├── TestChangeAsyncCustomDriver.cs.meta │ │ ├── TestChangeAsyncOverwrite.cs │ │ ├── TestChangeAsyncOverwrite.cs.meta │ │ ├── TestChangeAsyncSafe.cs │ │ ├── TestChangeAsyncSafe.cs.meta │ │ ├── TestChangeFromTransition.cs │ │ ├── TestChangeFromTransition.cs.meta │ │ ├── TestChangeState.cs │ │ ├── TestChangeState.cs.meta │ │ ├── TestMonoBehaviourUpdates.cs │ │ └── TestMonoBehaviourUpdates.cs.meta ├── Packages │ ├── manifest.json │ └── packages-lock.json └── ProjectSettings │ ├── AudioManager.asset │ ├── ClusterInputManager.asset │ ├── DynamicsManager.asset │ ├── EditorBuildSettings.asset │ ├── EditorSettings.asset │ ├── GraphicsSettings.asset │ ├── InputManager.asset │ ├── NavMeshAreas.asset │ ├── NavMeshLayers.asset │ ├── NetworkManager.asset │ ├── PackageManagerSettings.asset │ ├── Physics2DSettings.asset │ ├── PresetManager.asset │ ├── ProjectSettings.asset │ ├── ProjectVersion.txt │ ├── QualitySettings.asset │ ├── TagManager.asset │ ├── TimeManager.asset │ ├── UnityConnectSettings.asset │ ├── VFXManager.asset │ └── XRSettings.asset └── changelog.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | *.mat merge=unityyamlmerge eol=lf 2 | *.anim merge=unityyamlmerge eol=lf 3 | *.unity merge=unityyamlmerge eol=lf 4 | *.prefab merge=unityyamlmerge eol=lf 5 | *.physicsMaterial2D merge=unityyamlmerge eol=lf 6 | *.physicMaterial merge=unityyamlmerge eol=lf 7 | *.asset merge=unityyamlmerge eol=lf 8 | *.meta merge=unityyamlmerge eol=lf 9 | *.controller merge=unityyamlmerge eol=lf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | */Library 2 | */Assets/UnityVS 3 | */Temp 4 | */obj 5 | */Assets/UnityVS.meta 6 | */.vs 7 | */_Resharper.* 8 | */.idea 9 | */Logs 10 | 11 | */Assets/Plugins/Editor/Jetbrains/** 12 | */Assets/Plugins/Editor/Jetbrains.meta 13 | 14 | *.DotSettings 15 | *.DotSettings.user 16 | *.unityproj 17 | *.suo -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Made With Monster Love (pty) ltd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Simple Finite State Machine for Unity (C#) 2 | 3 | State machines are a very effective way to manage game state, either on your main game play object (Game Over, Restart, Continue etc) or UI (buttonHover, buttonPress etc) or on individual actors and NPCs (AI behaviours, Animations, etc). The following is a simple state machine that should work well within any Unity context. 4 | 5 | ## Designed for simplicity 6 | 7 | The textbook state machine implementation, and by extension other C# state machine libraries, have a tendency towards complicated configuration or excessive boilerplate. StateMachines are incredibly useful though - administrative overhead should never prevent us from improving readability, fixing bugs, and otherwise writing good code. 8 | 9 | * **Create states at the speed of thought:** Just add Enum fields! 10 | * **Effectively reason about your code:** Everything is in one place directly inside your MonoBehaviour. 11 | * **Use what you know about Unity:** Doing things the "Unity" way avoids unexpected weirdness and side effects. 12 | * **Only write the methods you're going to use:** Clever under-the-hood reflection saves you from writing tedious boilerplate. 13 | 14 | However, working programmers still need to ship production code. Correctness and performance should not be sacrificed in the name of convenience. 15 | 16 | * Extensive unit test coverage 17 | * Garbage allocation free after initialization 18 | * Battle hardened and shipped in production code 19 | * Suports iOS/Android/IL2CPP 20 | 21 | 22 | ## Usage 23 | 24 | The included example project (for Unity 2019.4) shows the State Machine in action. However, the following is everything you need to get going immediately: 25 | 26 | ```C# 27 | using MonsterLove.StateMachine; //1. Remember the using statement 28 | 29 | public class MyGameplayScript : MonoBehaviour 30 | { 31 | public enum States 32 | { 33 | Init, 34 | Play, 35 | Win, 36 | Lose 37 | } 38 | 39 | StateMachine fsm; 40 | 41 | void Awake(){ 42 | fsm = new StateMachine(this); //2. The main bit of "magic". 43 | 44 | fsm.ChangeState(States.Init); //3. Easily trigger state transitions 45 | } 46 | 47 | void Init_Enter() 48 | { 49 | Debug.Log("Ready"); 50 | } 51 | 52 | void Play_Enter() 53 | { 54 | Debug.Log("Spawning Player"); 55 | } 56 | 57 | void Play_FixedUpdate() 58 | { 59 | Debug.Log("Doing Physics stuff"); 60 | } 61 | 62 | void Play_Update() 63 | { 64 | if(player.health <= 0) 65 | { 66 | fsm.ChangeState(States.Lose); //3. Easily trigger state transitions 67 | } 68 | } 69 | 70 | void Play_Exit() 71 | { 72 | Debug.Log("Despawning Player"); 73 | } 74 | 75 | void Win_Enter() 76 | { 77 | Debug.Log("Game Over - you won!"); 78 | } 79 | 80 | void Lose_Enter() 81 | { 82 | Debug.Log("Game Over - you lost!"); 83 | } 84 | 85 | } 86 | ``` 87 | 88 | ### State Methods are defined by underscore convention ( `StateName_Method` ) 89 | 90 | Like MonoBehavior methods (`Awake`, `Updates`, etc), state methods are defined by convention. Declare a method in the format `StateName_Method`, and this will be associated with any matching names in the provided enum. 91 | 92 | ```C# 93 | void enum States 94 | { 95 | Play, 96 | } 97 | 98 | 99 | //Coroutines are supported, simply return IEnumerator 100 | IEnumerator Play_Enter() 101 | { 102 | yield return new WaitForSeconds(1); 103 | 104 | Debug.Log("Start"); 105 | } 106 | 107 | 108 | IEnumerator Play_Exit() 109 | { 110 | yield return new WaitForSeconds(1); 111 | } 112 | 113 | void Play_Finally() 114 | { 115 | Debug.Log("GameOver"); 116 | } 117 | ``` 118 | These built-in methods are always available, triggered automatically by `ChangeState(States newState)` calls: 119 | - `Enter` 120 | - `Exit` 121 | - `Finally` 122 | 123 | Both `Enter` and `Exit` support co-routines, simply return `IEnumerator`. However, return `void`, and they will be called immediately with no overhead. `Finally` is always called after `Exit` and provides an opportunity to perform clean-up and hygiene in special cases where the `Exit` routine might be interrupted before completing (see the Transitions heading). 124 | 125 | ## Data-Driven State Events 126 | 127 | To define additional events, we need to specify a `Driver`. 128 | 129 | ```C# 130 | public class Driver 131 | { 132 | StateEvent Update; 133 | StateEvent OnCollisionEnter; 134 | StateEvent OnHealthPickup; 135 | } 136 | ``` 137 | 138 | This is a very simple class. It doesn't have to be called `Driver`; the only constraint is that it must contain `StateEvent` fields. When we pass this to our state machine definition, it will take care of everything needed to set up new State event hooks. 139 | 140 | ```C# 141 | StateMachine fsm; 142 | 143 | void Awake(){ 144 | fsm = new StateMachine(this); 145 | } 146 | 147 | void Play_Enter() 148 | { 149 | Debug.Log("Started"); 150 | } 151 | 152 | void Play_Update() 153 | { 154 | Debug.Log("Ticked"); 155 | } 156 | 157 | void Play_OnHealthPickup(int health) 158 | { 159 | //Add to player health 160 | } 161 | 162 | ``` 163 | 164 | As these are custom events, the final step is to tell the state machine when these should be fired. 165 | 166 | ```C# 167 | void Update() 168 | { 169 | fsm.Driver.Update.Invoke(); 170 | } 171 | 172 | void OnCollisionEnter(Collision collision) 173 | { 174 | fsm.Driver.OnCollisionEnter.Invoke(collision); 175 | } 176 | 177 | void OnHealthPickup(int health) 178 | { 179 | fsm.Driver.OnHealthPickup.Invoke(); 180 | } 181 | ``` 182 | 183 | ##### Driver Deep-Dive 184 | 185 | Compared to the rest of the StateMachine, the `Driver` might elicit a reaction of: *"Hey! You said there wasn't going to be any funny business here!"* 186 | 187 | Indeed, there aren't many analogues in either C# or Unity. Before `v4.0`, the state machine would dynamically assign a `StateMachineRunner` component that would call `FixedUpdate`,`Update` & `LateUpate` hooks. (For backwards compatibility this is still the default behaviour when omitting a `Driver`). This worked, but additional hooks meant forking the `StateMachineRunner` class. Also, as a separate MonoBehaviour, it has it's own script execution order which could sometimes lead to oddities. 188 | 189 | But with the user responsible for invoking events - eg `fsm.Drive.Update.Invoke()`, it becomes much easier to reason about the lifecycle of the fsm. No more having to guess whether the StateMachine will update before or after the rest of the class, because the trigger is right there. It can be moved to right spot in the main `Update()` call. 190 | 191 | ```C# 192 | void Update() 193 | { 194 | //Do Stuff 195 | 196 | fsm.Driver.Update.Invoke(); 197 | 198 | //Do Other Stuff 199 | } 200 | 201 | void Play_Update() 202 | { 203 | //No guessing when this happens 204 | } 205 | ``` 206 | 207 | The real power shines when we consider another anti-pattern. Calling a state change from outside the state machine can lead to unintended side-effects. Imagine the following scenario where a global call causes a state transition. However without 208 | 209 | ```C# 210 | public void EndGame() 211 | { 212 | fsm.ChangeState(States.GameOver); 213 | } 214 | 215 | void Idle_Update() 216 | { 217 | //Changing to GameOver would cause unintended things to happen 218 | } 219 | 220 | void Play_Update() 221 | { 222 | //GameOver is legal 223 | } 224 | ``` 225 | 226 | Some libraries deal with this by defining transitons tables. However, it's possible to achieve a similar outcome using state events: 227 | ```C# 228 | public class Driver() 229 | { 230 | public StateEvent OnEndGame; 231 | } 232 | 233 | public void EndGame() 234 | { 235 | fsm.Driver.OnEndGame.Invoke(); 236 | } 237 | 238 | void Idle_Update() 239 | { 240 | //Changing to GameOver would cause unintended things to happen 241 | } 242 | 243 | void Play_Update() 244 | { 245 | //GameOver is legal 246 | } 247 | 248 | void Play_OnEndGame() 249 | { 250 | fsm.ChangeState(State.GameOver); 251 | } 252 | ``` 253 | Now the `Play` state is only state that can respond to EndGame calls. This creates an implicit transition table as sort of "free" side-effect. 254 | 255 | 256 | ## Async Transitions 257 | 258 | There is simple support for managing asynchronous state changes with long enter or exit coroutines. 259 | 260 | ```C# 261 | fsm.ChangeState(States.MyNextState, StateTransition.Safe); 262 | ``` 263 | 264 | The default is `StateTransition.Safe`. This will always allows the current state to finish both its enter and exit functions before transitioning to any new states. 265 | 266 | ```C# 267 | fsm.ChangeState(States.MyNextState, StateTransition.Overwrite); 268 | ``` 269 | 270 | `StateMahcine.Overwrite` will cancel any current transitions, and call the next state immediately. This means any code which has yet to run in enter and exit routines will be skipped. If you need to ensure you end with a particular configuration, the finally function will always be called: 271 | 272 | ```C# 273 | void MyCurrentState_Finally() 274 | { 275 | //Reset object to desired configuration 276 | } 277 | ``` 278 | 279 | ## Upgrading from v3 and above - April 2020 280 | 281 | Version `4.0` brings substantial innovation, however the API strives for backwards compatibility which means all the code you've already written does not need to change. However, the layout of the files inside the package has changed. To avoid errors it is recommended you delete the existing `MonsterLove` folder containing `StateMachine.cs` and related files, then reimport the new package. 282 | 283 | ## Performance & Limitations 284 | 285 | ##### Design Philosophy 286 | 287 | The state machine is designed to maximise simplicity for the end-user. To achieve this, under the hood lies some intricate reflection "magic". Reflection is a controversial choice because it is slow - and that's no exception here. However, we seek to balance the trade-off by limiting all the reflection to a single call when the state machine is initialised. This does degrade instantiation performance, however, instantiation is already slow. It's expected that strategies such as object pooling (recycling objects spawned on startup instead of at runtime) are already in effect, which moves this cost to a time when the user is unlikely to notice it. 288 | 289 | Once the initialisation cost has been swallowed, the State Machine aims to be a good citizen at runtime, avoiding allocations that cause garbage pressure and aiming for respectable performance. Ensuring correctness does mean that calling StateEvents' `Invoke()` is slower than naked method calls. Over tens of thousands of instances this can add up to a significant overhead. In these use cases (multiple 1000's of objects) it is recommended to replace the state machine with something hand-tuned. 290 | 291 | However, for most general use cases, eg manager classes, or other items with low instance counts (10's or 100's) - the difference in performance should absolutely not be something you need to think about. 292 | 293 | ##### Memory Allocation Free? 294 | This is designed to target mobile, as such should be memory allocation free. However the same rules apply as with the rest of Unity in regards to using `IEnumerator` and Coroutines. 295 | 296 | ##### Windows Store Platforms 297 | Due to differences in the Windows Store flavour of .Net and WinRT, this platform is currently incompatible. More details available in this [issue](https://github.com/thefuntastic/Unity3d-Finite-State-Machine/issues/4). 298 | 299 | ## License 300 | MIT License 301 | 302 | ## Notes 303 | 304 | This is state machine is used extensively on the [Made With Monster Love](http://www.madewithmonsterlove.com) title [Cadence](http://store.steampowered.com/app/362800/Cadence/), a puzzle game about making music. 305 | 306 | This library owes its origins to the state machine from the now defunct Unity Gems (available via [The Internet Archive](http://web.archive.org/web/20140902150909/http://unitygems.com/fsm1/) as of Nov 2014). The original project, however, had many short comings that made usage difficult. Adhering to the principle that a library should do one thing really well, what we have now is perhaps the easiest and most straight forward State Machine in existence for Unity. 307 | 308 | ##### Feedback and suggestions: 309 | - http://www.twitter.com/thefuntastic 310 | -------------------------------------------------------------------------------- /StateMachine/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.sln 3 | *.csproj 4 | *.pidb 5 | *.userprefs -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 524052bb489d0844f93a363c1c7210ec 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8608d2a9134ccf94c8f0036d61c0b622 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Runtime/Drivers.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6d19f3162564ec54aa39985d42873958 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Runtime/Drivers/StateDriverRunner.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019 Made With Monster Love (Pty) Ltd 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to 6 | * deal in the Software without restriction, including without limitation the 7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 | * OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | namespace MonsterLove.StateMachine 24 | { 25 | public class StateDriverRunner 26 | { 27 | public StateEvent FixedUpdate; 28 | public StateEvent Update; 29 | public StateEvent LateUpdate; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Runtime/Drivers/StateDriverRunner.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8580b7087fdeecd4fb42025a957800f3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Runtime/Drivers/StateDriverUnity.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019 Made With Monster Love (Pty) Ltd 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to 6 | * deal in the Software without restriction, including without limitation the 7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 | * OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | using UnityEngine; 24 | 25 | namespace MonsterLove.StateMachine 26 | { 27 | public class StateDriverUnity 28 | { 29 | public StateEvent Awake; 30 | public StateEvent LateUpdate; 31 | public StateEvent OnAnimatorIK; 32 | public StateEvent OnAnimatorMove; 33 | public StateEvent OnApplicationFocus; 34 | public StateEvent OnApplicationPause; 35 | public StateEvent OnApplicationQuit; 36 | public StateEvent OnAudioFilterRead; 37 | public StateEvent OnBecameInvisible; 38 | public StateEvent OnBecameVisible; 39 | public StateEvent OnCollisionEnter; 40 | public StateEvent OnCollisionEnter2D; 41 | public StateEvent OnCollisionExit; 42 | public StateEvent OnCollisionExit2D; 43 | public StateEvent OnCollisionStay; 44 | public StateEvent OnCollisionStay2D; 45 | public StateEvent OnConnectedToServer; 46 | public StateEvent OnControllerColliderHit; 47 | public StateEvent OnDestroy; 48 | public StateEvent OnDisable; 49 | public StateEvent OnDrawGizmos; 50 | public StateEvent OnDrawGizmosSelected; 51 | public StateEvent OnEnable; 52 | public StateEvent OnGUI; 53 | public StateEvent OnJointBreak; 54 | public StateEvent OnJointBreak2D; 55 | public StateEvent OnMouseDown; 56 | public StateEvent OnMouseDrag; 57 | public StateEvent OnMouseEnter; 58 | public StateEvent OnMouseExit; 59 | public StateEvent OnMouseOver; 60 | public StateEvent OnMouseUp; 61 | public StateEvent OnMouseUpAsButton; 62 | public StateEvent OnParticleCollision; 63 | public StateEvent OnParticleSystemStopped; 64 | public StateEvent OnParticleTrigger; 65 | public StateEvent OnPostRender; 66 | public StateEvent OnPreCull; 67 | public StateEvent OnRenderImage; 68 | public StateEvent OnRenderObject; 69 | public StateEvent OnTransformChildrenChanged; 70 | public StateEvent OnTransformParentChanged; 71 | public StateEvent OnTriggerEnter; 72 | public StateEvent OnTriggerEnter2D; 73 | public StateEvent OnTriggerExit; 74 | public StateEvent OnTriggerExit2D; 75 | public StateEvent OnTriggerStay; 76 | public StateEvent OnTriggerStay2D; 77 | public StateEvent OnValidate; 78 | public StateEvent OnWillRenderOjbect; 79 | public StateEvent Reset; 80 | public StateEvent Start; 81 | public StateEvent Update; 82 | 83 | //Unity Networking Deprecated 84 | //public StateEvent OnDisconnectedFromServer; 85 | //public StateEvent OnFailedToConnect; 86 | //public StateEvent OnFailedToConnectToMasterServer; 87 | //public StateEvent OnMasterServerEvent; 88 | //public StateEvent OnNetworkInstantiate; 89 | //public StateEvent OnPlayerConnected; 90 | //public StateEvent OnPlayerDisconnected; 91 | //public StateEvent OnSerializeNetworkView; 92 | //public StateEvent OnSeverInitialized; 93 | 94 | } 95 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Runtime/Drivers/StateDriverUnity.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: de0d37dba910471099253a3cc12484fb 3 | timeCreated: 1567762416 -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Runtime/Events.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 26a1a054d8aa3a94cac21be251c4e634 3 | timeCreated: 1568024794 -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Runtime/Events/StateEvent.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019 Made With Monster Love (Pty) Ltd 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to 6 | * deal in the Software without restriction, including without limitation the 7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 | * OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | using System; 24 | using System.Collections.Generic; 25 | 26 | // Warning! 27 | // This is somewhat fragile Event pattern implementation. Recommended they aren't used outside of the state machine 28 | // 29 | namespace MonsterLove.StateMachine 30 | { 31 | public class StateEvent 32 | { 33 | private Func getStateInt; 34 | private Func isInvokeAllowed; 35 | private Action[] routingTable; 36 | 37 | public StateEvent(Func isInvokeAllowed, Func stateProvider, int capacity) 38 | { 39 | this.isInvokeAllowed = isInvokeAllowed; 40 | this.getStateInt = stateProvider; 41 | routingTable = new Action[capacity]; 42 | } 43 | 44 | internal void AddListener(int stateInt, Action listener) 45 | { 46 | routingTable[stateInt] = listener; 47 | } 48 | 49 | public void Invoke() 50 | { 51 | if (isInvokeAllowed != null && !isInvokeAllowed()) 52 | { 53 | return; 54 | } 55 | 56 | Action call = routingTable[getStateInt()]; 57 | if (call != null) 58 | { 59 | call(); 60 | return; 61 | } 62 | } 63 | } 64 | 65 | public class StateEvent 66 | { 67 | private Func getStateInt; 68 | private Func isInvokeAllowed; 69 | private Action[] routingTable; 70 | 71 | public StateEvent(Func isInvokeAllowed, Func stateProvider, int capacity) 72 | { 73 | this.isInvokeAllowed = isInvokeAllowed; 74 | this.getStateInt = stateProvider; 75 | routingTable = new Action[capacity]; 76 | } 77 | 78 | internal void AddListener(int stateInt, Action listener) 79 | { 80 | routingTable[stateInt] = listener; 81 | } 82 | 83 | public void Invoke(T param) 84 | { 85 | if (isInvokeAllowed != null && !isInvokeAllowed()) 86 | { 87 | return; 88 | } 89 | 90 | Action call = routingTable[getStateInt()]; 91 | if (call != null) 92 | { 93 | call(param); 94 | return; 95 | } 96 | } 97 | } 98 | 99 | public class StateEvent 100 | { 101 | private Func getStateInt; 102 | private Func isInvokeAllowed; 103 | private Action[] routingTable; 104 | 105 | public StateEvent(Func isInvokeAllowed, Func stateProvider, int capacity) 106 | { 107 | this.isInvokeAllowed = isInvokeAllowed; 108 | this.getStateInt = stateProvider; 109 | routingTable = new Action[capacity]; 110 | } 111 | 112 | internal void AddListener(int stateInt, Action listener) 113 | { 114 | routingTable[stateInt] = listener; 115 | } 116 | 117 | public void Invoke(T1 param1, T2 param2) 118 | { 119 | if (isInvokeAllowed != null && !isInvokeAllowed()) 120 | { 121 | return; 122 | } 123 | 124 | Action call = routingTable[getStateInt()]; 125 | if (call != null) 126 | { 127 | call(param1, param2); 128 | return; 129 | } 130 | } 131 | } 132 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Runtime/Events/StateEvent.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a130ac4a15eb4a0cabf018a385e09999 3 | timeCreated: 1568024803 -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Runtime/MonsterLove.StateMachine.Runtime.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MonsterLove.StateMachine.Runtime", 3 | "references": [], 4 | "includePlatforms": [], 5 | "excludePlatforms": [], 6 | "allowUnsafeCode": false, 7 | "overrideReferences": false, 8 | "precompiledReferences": [], 9 | "autoReferenced": true, 10 | "defineConstraints": [], 11 | "versionDefines": [], 12 | "noEngineReferences": false 13 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Runtime/MonsterLove.StateMachine.Runtime.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 39f9fc2c98cf6654498562b4bdd17a1e 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Runtime/StateMachine.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6da868d186fa05342bd37fb8e63d3666 3 | timeCreated: 1457605040 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Runtime/StateMachineRunner.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019 Made With Monster Love (Pty) Ltd 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to 6 | * deal in the Software without restriction, including without limitation the 7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 | * OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | using System; 24 | using System.Collections; 25 | using System.Collections.Generic; 26 | using UnityEngine; 27 | 28 | namespace MonsterLove.StateMachine 29 | { 30 | public class StateMachineRunner : MonoBehaviour 31 | { 32 | private List> stateMachineList = new List>(); 33 | 34 | /// 35 | /// Creates a stateMachine token object which is used to managed to the state of a monobehaviour. 36 | /// 37 | /// An Enum listing different state transitions 38 | /// The component whose state will be managed 39 | /// 40 | public StateMachine Initialize(MonoBehaviour component) where TState : struct, IConvertible, IComparable 41 | { 42 | var fsm = new StateMachine(component); 43 | 44 | stateMachineList.Add(fsm); 45 | 46 | return fsm; 47 | } 48 | 49 | /// 50 | /// Creates a stateMachine token object which is used to managed to the state of a monobehaviour. Will automatically transition the startState 51 | /// 52 | /// An Enum listing different state transitions 53 | /// The component whose state will be managed 54 | /// The default start state 55 | /// 56 | public StateMachine Initialize(MonoBehaviour component, TState startState) where TState : struct, IConvertible, IComparable 57 | { 58 | var fsm = Initialize(component); 59 | 60 | fsm.ChangeState(startState); 61 | 62 | return fsm; 63 | } 64 | 65 | void FixedUpdate() 66 | { 67 | for (int i = 0; i < stateMachineList.Count; i++) 68 | { 69 | var fsm = stateMachineList[i]; 70 | if (!fsm.IsInTransition && fsm.Component.enabled) 71 | { 72 | fsm.Driver.FixedUpdate.Invoke(); 73 | } 74 | } 75 | } 76 | 77 | void Update() 78 | { 79 | for (int i = 0; i < stateMachineList.Count; i++) 80 | { 81 | var fsm = stateMachineList[i]; 82 | if (!fsm.IsInTransition && fsm.Component.enabled) 83 | { 84 | fsm.Driver.Update.Invoke(); 85 | } 86 | } 87 | } 88 | 89 | void LateUpdate() 90 | { 91 | for (int i = 0; i < stateMachineList.Count; i++) 92 | { 93 | var fsm = stateMachineList[i]; 94 | if (!fsm.IsInTransition && fsm.Component.enabled) 95 | { 96 | fsm.Driver.LateUpdate.Invoke(); 97 | } 98 | } 99 | } 100 | 101 | public static void DoNothing() 102 | { 103 | } 104 | 105 | public static IEnumerator DoNothingCoroutine() 106 | { 107 | yield break; 108 | } 109 | } 110 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Runtime/StateMachineRunner.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5e2a0c63ef281b44a823365c3d5bffcd 3 | timeCreated: 1457616174 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Runtime/StateMapping.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019 Made With Monster Love (Pty) Ltd 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to 6 | * deal in the Software without restriction, including without limitation the 7 | * rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 | * OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | using System; 24 | using System.Collections; 25 | using System.Collections.Generic; 26 | using UnityEngine; 27 | 28 | namespace MonsterLove.StateMachine 29 | { 30 | internal class StateMapping where TState : struct, IConvertible, IComparable 31 | where TDriver : class, new() 32 | { 33 | public TState state; 34 | 35 | public bool hasEnterRoutine; 36 | public Action EnterCall = StateMachineRunner.DoNothing; 37 | public Func EnterRoutine = StateMachineRunner.DoNothingCoroutine; 38 | 39 | public bool hasExitRoutine; 40 | public Action ExitCall = StateMachineRunner.DoNothing; 41 | public Func ExitRoutine = StateMachineRunner.DoNothingCoroutine; 42 | 43 | public Action Finally = StateMachineRunner.DoNothing; 44 | 45 | private Func stateProviderCallback; 46 | private StateMachine fsm; 47 | 48 | public StateMapping(StateMachine fsm, TState state, Func stateProvider) 49 | { 50 | this.fsm = fsm; 51 | this.state = state; 52 | stateProviderCallback = stateProvider; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Runtime/StateMapping.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0a9d115393f24d76a917d05ac6a87127 3 | timeCreated: 1568111091 -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3268d4567b17b144c93ebe97e1b38779 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/Prefabs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1b25c0e4b36a737478915ab5422e5775 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/Prefabs/Item.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &4204478616006888474 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 7356218733581437328} 12 | - component: {fileID: 7630017851788502069} 13 | - component: {fileID: 6320050345510877602} 14 | - component: {fileID: 3275343476624940446} 15 | - component: {fileID: 2663155548185288521} 16 | m_Layer: 0 17 | m_Name: Item 18 | m_TagString: Untagged 19 | m_Icon: {fileID: 0} 20 | m_NavMeshLayer: 0 21 | m_StaticEditorFlags: 0 22 | m_IsActive: 1 23 | --- !u!4 &7356218733581437328 24 | Transform: 25 | m_ObjectHideFlags: 0 26 | m_CorrespondingSourceObject: {fileID: 0} 27 | m_PrefabInstance: {fileID: 0} 28 | m_PrefabAsset: {fileID: 0} 29 | m_GameObject: {fileID: 4204478616006888474} 30 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 31 | m_LocalPosition: {x: 0, y: 0, z: 0} 32 | m_LocalScale: {x: 1, y: 1, z: 1} 33 | m_Children: [] 34 | m_Father: {fileID: 0} 35 | m_RootOrder: 0 36 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 37 | --- !u!33 &7630017851788502069 38 | MeshFilter: 39 | m_ObjectHideFlags: 0 40 | m_CorrespondingSourceObject: {fileID: 0} 41 | m_PrefabInstance: {fileID: 0} 42 | m_PrefabAsset: {fileID: 0} 43 | m_GameObject: {fileID: 4204478616006888474} 44 | m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0} 45 | --- !u!23 &6320050345510877602 46 | MeshRenderer: 47 | m_ObjectHideFlags: 0 48 | m_CorrespondingSourceObject: {fileID: 0} 49 | m_PrefabInstance: {fileID: 0} 50 | m_PrefabAsset: {fileID: 0} 51 | m_GameObject: {fileID: 4204478616006888474} 52 | m_Enabled: 1 53 | m_CastShadows: 1 54 | m_ReceiveShadows: 1 55 | m_DynamicOccludee: 1 56 | m_MotionVectors: 1 57 | m_LightProbeUsage: 1 58 | m_ReflectionProbeUsage: 1 59 | m_RayTracingMode: 2 60 | m_RenderingLayerMask: 1 61 | m_RendererPriority: 0 62 | m_Materials: 63 | - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} 64 | m_StaticBatchInfo: 65 | firstSubMesh: 0 66 | subMeshCount: 0 67 | m_StaticBatchRoot: {fileID: 0} 68 | m_ProbeAnchor: {fileID: 0} 69 | m_LightProbeVolumeOverride: {fileID: 0} 70 | m_ScaleInLightmap: 1 71 | m_ReceiveGI: 1 72 | m_PreserveUVs: 0 73 | m_IgnoreNormalsForChartDetection: 0 74 | m_ImportantGI: 0 75 | m_StitchLightmapSeams: 1 76 | m_SelectedEditorRenderState: 3 77 | m_MinimumChartSize: 4 78 | m_AutoUVMaxDistance: 0.5 79 | m_AutoUVMaxAngle: 89 80 | m_LightmapParameters: {fileID: 0} 81 | m_SortingLayerID: 0 82 | m_SortingLayer: 0 83 | m_SortingOrder: 0 84 | --- !u!136 &3275343476624940446 85 | CapsuleCollider: 86 | m_ObjectHideFlags: 0 87 | m_CorrespondingSourceObject: {fileID: 0} 88 | m_PrefabInstance: {fileID: 0} 89 | m_PrefabAsset: {fileID: 0} 90 | m_GameObject: {fileID: 4204478616006888474} 91 | m_Material: {fileID: 0} 92 | m_IsTrigger: 0 93 | m_Enabled: 1 94 | m_Radius: 0.5 95 | m_Height: 2 96 | m_Direction: 1 97 | m_Center: {x: 0, y: 0, z: 0} 98 | --- !u!114 &2663155548185288521 99 | MonoBehaviour: 100 | m_ObjectHideFlags: 0 101 | m_CorrespondingSourceObject: {fileID: 0} 102 | m_PrefabInstance: {fileID: 0} 103 | m_PrefabAsset: {fileID: 0} 104 | m_GameObject: {fileID: 4204478616006888474} 105 | m_Enabled: 1 106 | m_EditorHideFlags: 0 107 | m_Script: {fileID: 11500000, guid: 0f92323e092843a7a057ef31db09f92d, type: 3} 108 | m_Name: 109 | m_EditorClassIdentifier: 110 | isTarget: 0 111 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/Prefabs/Item.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8f65e2077557e2a48bb201a371e5d29b 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5a0f0a984818fcf4db10db5d5455492c 3 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/Scripts/ColorChanger.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using MonsterLove.StateMachine; 6 | 7 | public class ColorChanger : MonoBehaviour 8 | { 9 | public enum States 10 | { 11 | Blue, 12 | Green, 13 | Red 14 | } 15 | 16 | public float interval; 17 | 18 | private Camera cam; 19 | 20 | private StateMachine fsm; 21 | 22 | void Awake() 23 | { 24 | cam = Camera.main; 25 | 26 | fsm = StateMachine.Initialize(this); 27 | } 28 | 29 | IEnumerator Blue_Enter() 30 | { 31 | cam.backgroundColor = Color.blue * 0.5f; 32 | yield return new WaitForSeconds(interval); 33 | 34 | fsm.ChangeState(States.Red); 35 | } 36 | 37 | IEnumerator Red_Enter() 38 | { 39 | cam.backgroundColor = Color.red * 0.5f; 40 | yield return new WaitForSeconds(interval); 41 | 42 | fsm.ChangeState(States.Green); 43 | } 44 | 45 | IEnumerator Green_Enter() 46 | { 47 | cam.backgroundColor = Color.green * 0.5f; 48 | yield return new WaitForSeconds(interval); 49 | 50 | fsm.ChangeState(States.Blue); 51 | } 52 | 53 | void OnGUI() 54 | { 55 | if(GUI.Button(new Rect(Screen.width - 150, 50, 100, 20), "Disco Time!")) 56 | { 57 | fsm.ChangeState(States.Blue, StateTransition.Overwrite); 58 | } 59 | 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/Scripts/ColorChanger.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a57cafd734b9e8d4da74fd1b24e6107e 3 | timeCreated: 1457603986 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/Scripts/ExampleAdvanced.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using MonsterLove.StateMachine; 3 | using UnityEngine; 4 | 5 | public class ExampleAdvanced : MonoBehaviour 6 | { 7 | public Item prefab; 8 | public float roundTime; 9 | 10 | private List spawnedItems; 11 | private Item targetItem; 12 | private float playStartTime; 13 | 14 | private StateMachine fsm; 15 | 16 | private void Awake() 17 | { 18 | //Initialize the state machine 19 | fsm = new StateMachine(this); 20 | fsm.ChangeState(States.Idle); //Remember to set an initial state! 21 | } 22 | 23 | private void Update() 24 | { 25 | fsm.Driver.Update.Invoke(); //Tap the state machine into Unity's update loop. We could choose to call this from anywhere though! 26 | } 27 | 28 | void OnGUI() 29 | { 30 | fsm.Driver.OnGUI.Invoke(); //Tap into the OnGUI update loop. 31 | } 32 | 33 | void DestroyItem(Item item) 34 | { 35 | item.Triggered -= fsm.Driver.OnItemSelected.Invoke; //Good hygiene, always remove your listeners when you are done! 36 | Destroy(item.gameObject); 37 | } 38 | 39 | #region fsm 40 | 41 | public enum States 42 | { 43 | Idle, 44 | Play, 45 | GameWin, 46 | GameLose, 47 | } 48 | 49 | public class Driver 50 | { 51 | public StateEvent Update; 52 | public StateEvent OnGUI; 53 | public StateEvent OnItemSelected; 54 | } 55 | 56 | void Idle_OnGUI() 57 | { 58 | if (GUI.Button(new Rect(20, 20, 100, 30), "Begin")) 59 | { 60 | fsm.ChangeState(States.Play); 61 | } 62 | } 63 | 64 | void Play_Enter() 65 | { 66 | playStartTime = Time.time; 67 | 68 | int count = 10; 69 | int targetIndex = Random.Range(0, count); 70 | spawnedItems = new List(count); 71 | for (int i = 0; i < count; i++) 72 | { 73 | var pos2D = Random.insideUnitCircle * 5; 74 | var item = (Item) Instantiate(prefab, new Vector3(pos2D.x, 0, pos2D.y), Quaternion.identity); 75 | item.isTarget = (i == targetIndex); 76 | item.Triggered += fsm.Driver.OnItemSelected.Invoke; //Pipe external events into the fsm - this is very powerful! 77 | spawnedItems.Add(item); 78 | } 79 | } 80 | 81 | void Play_OnGUI() 82 | { 83 | float timeRemaining = roundTime - (Time.time - playStartTime); 84 | GUI.Label(new Rect(20, 20, 300, 30), "Click items to find the target"); 85 | GUI.Label(new Rect(20, 50, 300, 30), $"Time Remaining: {timeRemaining:n3}"); 86 | } 87 | 88 | void Play_Update() 89 | { 90 | if (Time.time - playStartTime >= roundTime) 91 | { 92 | fsm.ChangeState(States.GameLose); 93 | } 94 | } 95 | 96 | void Play_OnItemSelected(Item item) //Data driven events guarantee correctness - only the Play state responds to OnItemSelected events 97 | { 98 | if (item.isTarget) 99 | { 100 | targetItem = item; 101 | fsm.ChangeState(States.GameWin); 102 | } 103 | else 104 | { 105 | spawnedItems.Remove(item); 106 | DestroyItem(item); 107 | } 108 | } 109 | 110 | void GameWin_Enter() 111 | { 112 | spawnedItems.Remove(targetItem); 113 | 114 | for (int i = spawnedItems.Count - 1; i >= 0; i--) //Reverse order as we're modifying the list in place 115 | { 116 | var item = spawnedItems[i]; 117 | spawnedItems.Remove(item); 118 | DestroyItem(item); 119 | } 120 | } 121 | 122 | void GameWin_OnGUI() 123 | { 124 | GUI.Label(new Rect(20, 20, 300, 30), "Well done, you found it!"); 125 | 126 | if (GUI.Button(new Rect(20, 50, 100, 30), "Restart")) 127 | { 128 | fsm.ChangeState(States.Idle); 129 | } 130 | } 131 | 132 | void GameWin_Exit() 133 | { 134 | DestroyItem(targetItem); 135 | targetItem = null; 136 | } 137 | 138 | void GameLose_Enter() 139 | { 140 | for (int i = spawnedItems.Count - 1; i >= 0; i--) //Reverse order as we're modifying the list in place 141 | { 142 | var item = spawnedItems[i]; 143 | spawnedItems.Remove(item); 144 | DestroyItem(item); 145 | } 146 | } 147 | 148 | void GameLose_OnGUI() 149 | { 150 | GUI.Label(new Rect(20, 20, 300, 30), "Bad luck, you didn't find it in time!"); 151 | 152 | if (GUI.Button(new Rect(20, 50, 100, 30), "Restart")) 153 | { 154 | fsm.ChangeState(States.Idle); 155 | } 156 | } 157 | 158 | 159 | #endregion 160 | 161 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/Scripts/ExampleAdvanced.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c086227322664a1ab09daecc44f8e5fa 3 | timeCreated: 1616755006 -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/Scripts/ExampleBasic.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using MonsterLove.StateMachine; 4 | 5 | public class ExampleBasic : MonoBehaviour 6 | { 7 | //Declare which states we'd like use 8 | public enum States 9 | { 10 | Init, 11 | Countdown, 12 | Play, 13 | Win, 14 | Lose 15 | } 16 | 17 | public float health = 100; 18 | public float damage = 20; 19 | 20 | private float startHealth; 21 | 22 | private StateMachine fsm; 23 | 24 | private void Awake() 25 | { 26 | startHealth = health; 27 | 28 | //Initialize State Machine Engine 29 | fsm = new StateMachine(this); 30 | fsm.ChangeState(States.Init); 31 | } 32 | 33 | void Update() 34 | { 35 | fsm.Driver.Update.Invoke(); 36 | } 37 | 38 | void OnGUI() 39 | { 40 | GUILayout.BeginArea(new Rect(50,50,120,40)); 41 | 42 | fsm.Driver.OnGUI.Invoke(); 43 | 44 | GUILayout.EndArea(); 45 | } 46 | 47 | void Init_Enter() 48 | { 49 | Debug.Log("Waiting for start button to be pressed"); 50 | } 51 | 52 | void Init_OnGUI() 53 | { 54 | if(GUILayout.Button("Start")) 55 | { 56 | fsm.ChangeState(States.Countdown); 57 | } 58 | } 59 | 60 | //We can return a coroutine, this is useful animations and the like 61 | IEnumerator Countdown_Enter() 62 | { 63 | health = startHealth; 64 | 65 | Debug.Log("Starting in 3..."); 66 | yield return new WaitForSeconds(0.5f); 67 | Debug.Log("Starting in 2..."); 68 | yield return new WaitForSeconds(0.5f); 69 | Debug.Log("Starting in 1..."); 70 | yield return new WaitForSeconds(0.5f); 71 | 72 | fsm.ChangeState(States.Play); 73 | } 74 | 75 | void Countdown_OnGUI() 76 | { 77 | GUILayout.Label("Look at Console"); 78 | } 79 | 80 | void Play_Enter() 81 | { 82 | Debug.Log("FIGHT!"); 83 | } 84 | 85 | void Play_Update() 86 | { 87 | health -= damage * Time.deltaTime; 88 | 89 | if(health < 0) 90 | { 91 | fsm.ChangeState(States.Lose); 92 | } 93 | } 94 | 95 | void Play_OnGUI() 96 | { 97 | if(GUILayout.Button("Make me win!")) 98 | { 99 | fsm.ChangeState(States.Win); 100 | } 101 | 102 | GUILayout.Label("Health: " + Mathf.Round(health).ToString()); 103 | } 104 | 105 | void Play_Exit() 106 | { 107 | Debug.Log("Game Over"); 108 | } 109 | 110 | void Lose_Enter() 111 | { 112 | Debug.Log("Lost"); 113 | } 114 | 115 | void Lose_OnGUI() 116 | { 117 | if(GUILayout.Button("Play Again")) 118 | { 119 | fsm.ChangeState(States.Countdown); 120 | } 121 | } 122 | 123 | void Win_Enter() 124 | { 125 | Debug.Log("Won"); 126 | } 127 | 128 | void Win_OnGUI() 129 | { 130 | if(GUILayout.Button("Play Again")) 131 | { 132 | fsm.ChangeState(States.Countdown); 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/Scripts/ExampleBasic.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e1b8c2ce0ae416a4ebf4865c20d2d12e 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/Scripts/Item.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | public class Item : MonoBehaviour 5 | { 6 | public event Action Triggered; 7 | 8 | public bool isTarget; 9 | 10 | public void OnMouseDown() 11 | { 12 | if (Triggered != null) 13 | { 14 | Triggered(this); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/Scripts/Item.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0f92323e092843a7a057ef31db09f92d 3 | timeCreated: 1616756619 -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/Scripts/MonsterLove.StateMachine.Samples.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MonsterLove.StateMachine.Samples", 3 | "references": [ 4 | "GUID:39f9fc2c98cf6654498562b4bdd17a1e" 5 | ], 6 | "includePlatforms": [], 7 | "excludePlatforms": [], 8 | "allowUnsafeCode": false, 9 | "overrideReferences": false, 10 | "precompiledReferences": [], 11 | "autoReferenced": true, 12 | "defineConstraints": [], 13 | "versionDefines": [], 14 | "noEngineReferences": false 15 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/Scripts/MonsterLove.StateMachine.Samples.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 64e8a9da2ff291b458d3a67fda350daa 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/Scripts/Perf.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f34f140b3438bc944beff20f0b786636 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/Scripts/Perf/StressTest.cs: -------------------------------------------------------------------------------- 1 |  2 | using System; 3 | using MonsterLove.StateMachine; 4 | using UnityEngine; 5 | using UnityEngine.Profiling; 6 | 7 | public class StressTest : MonoBehaviour 8 | { 9 | enum States 10 | { 11 | State0, 12 | State1, 13 | State2, 14 | State3, 15 | State4, 16 | State5, 17 | State6, 18 | State7, 19 | State8, 20 | State9, 21 | State10, 22 | State11, 23 | State12, 24 | State13, 25 | State14, 26 | } 27 | 28 | public class Driver 29 | { 30 | public StateEvent Update; 31 | public StateEvent OnChanged; 32 | } 33 | 34 | private StateMachine fsm; 35 | 36 | private int value = 0; 37 | 38 | public void Awake() 39 | { 40 | fsm = new StateMachine(this); 41 | fsm.ChangeState(States.State1); 42 | } 43 | 44 | private void Update() 45 | { 46 | Profiler.BeginSample("Fsm_Invoke"); 47 | for (int i = 0; i < 10000; i++) 48 | { 49 | fsm.Driver.Update.Invoke(); 50 | fsm.Driver.OnChanged.Invoke(i); 51 | } 52 | Profiler.EndSample(); 53 | 54 | Profiler.BeginSample("Fsm_Native"); 55 | for (int i = 0; i < 10000; i++) 56 | { 57 | State1_Update(); 58 | State1_OnChanged(i); 59 | } 60 | Profiler.EndSample(); 61 | } 62 | 63 | void State1_Update() 64 | { 65 | value++; 66 | } 67 | 68 | void State1_OnChanged(int value) 69 | { 70 | this.value = value; 71 | } 72 | 73 | void State2_Update() 74 | { 75 | value++; 76 | } 77 | 78 | void State2_OnChanged(int value) 79 | { 80 | this.value = -value; 81 | } 82 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/Scripts/Perf/StressTest.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5feefe5bbb45416ca0f4953ecfff49da 3 | timeCreated: 1616777700 -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/StateMachine_Advanced.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.2, g: 0.2, b: 0.2, a: 1} 24 | m_AmbientEquatorColor: {r: 0.2, g: 0.2, b: 0.2, a: 1} 25 | m_AmbientGroundColor: {r: 0.2, g: 0.2, b: 0.2, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 3 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &4 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 1 59 | m_BakeResolution: 50 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 0 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 0 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 1024 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 1 75 | m_BakeBackend: 0 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 500 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 500 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 0 83 | m_PVRDenoiserTypeDirect: 0 84 | m_PVRDenoiserTypeIndirect: 0 85 | m_PVRDenoiserTypeAO: 0 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 0 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_UseShadowmask: 0 102 | --- !u!196 &5 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666666 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | debug: 122 | m_Flags: 0 123 | m_NavMeshData: {fileID: 0} 124 | --- !u!1 &335347781 125 | GameObject: 126 | m_ObjectHideFlags: 0 127 | m_CorrespondingSourceObject: {fileID: 0} 128 | m_PrefabInstance: {fileID: 0} 129 | m_PrefabAsset: {fileID: 0} 130 | serializedVersion: 6 131 | m_Component: 132 | - component: {fileID: 335347786} 133 | - component: {fileID: 335347785} 134 | - component: {fileID: 335347782} 135 | m_Layer: 0 136 | m_Name: Main Camera 137 | m_TagString: MainCamera 138 | m_Icon: {fileID: 0} 139 | m_NavMeshLayer: 0 140 | m_StaticEditorFlags: 0 141 | m_IsActive: 1 142 | --- !u!81 &335347782 143 | AudioListener: 144 | m_ObjectHideFlags: 0 145 | m_CorrespondingSourceObject: {fileID: 0} 146 | m_PrefabInstance: {fileID: 0} 147 | m_PrefabAsset: {fileID: 0} 148 | m_GameObject: {fileID: 335347781} 149 | m_Enabled: 1 150 | --- !u!20 &335347785 151 | Camera: 152 | m_ObjectHideFlags: 0 153 | m_CorrespondingSourceObject: {fileID: 0} 154 | m_PrefabInstance: {fileID: 0} 155 | m_PrefabAsset: {fileID: 0} 156 | m_GameObject: {fileID: 335347781} 157 | m_Enabled: 1 158 | serializedVersion: 2 159 | m_ClearFlags: 1 160 | m_BackGroundColor: {r: 0.2519135, g: 0.28969136, b: 0.3490566, a: 0.019607844} 161 | m_projectionMatrixMode: 1 162 | m_GateFitMode: 2 163 | m_FOVAxisMode: 0 164 | m_SensorSize: {x: 36, y: 24} 165 | m_LensShift: {x: 0, y: 0} 166 | m_FocalLength: 50 167 | m_NormalizedViewPortRect: 168 | serializedVersion: 2 169 | x: 0 170 | y: 0 171 | width: 1 172 | height: 1 173 | near clip plane: 0.3 174 | far clip plane: 1000 175 | field of view: 60 176 | orthographic: 0 177 | orthographic size: 5 178 | m_Depth: -1 179 | m_CullingMask: 180 | serializedVersion: 2 181 | m_Bits: 4294967295 182 | m_RenderingPath: -1 183 | m_TargetTexture: {fileID: 0} 184 | m_TargetDisplay: 0 185 | m_TargetEye: 3 186 | m_HDR: 0 187 | m_AllowMSAA: 1 188 | m_AllowDynamicResolution: 0 189 | m_ForceIntoRT: 0 190 | m_OcclusionCulling: 1 191 | m_StereoConvergence: 10 192 | m_StereoSeparation: 0.022 193 | --- !u!4 &335347786 194 | Transform: 195 | m_ObjectHideFlags: 0 196 | m_CorrespondingSourceObject: {fileID: 0} 197 | m_PrefabInstance: {fileID: 0} 198 | m_PrefabAsset: {fileID: 0} 199 | m_GameObject: {fileID: 335347781} 200 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 201 | m_LocalPosition: {x: 0, y: 0, z: -9.6} 202 | m_LocalScale: {x: 1, y: 1, z: 1} 203 | m_Children: [] 204 | m_Father: {fileID: 1431333937} 205 | m_RootOrder: 0 206 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 207 | --- !u!1 &1431333936 208 | GameObject: 209 | m_ObjectHideFlags: 0 210 | m_CorrespondingSourceObject: {fileID: 0} 211 | m_PrefabInstance: {fileID: 0} 212 | m_PrefabAsset: {fileID: 0} 213 | serializedVersion: 6 214 | m_Component: 215 | - component: {fileID: 1431333937} 216 | m_Layer: 0 217 | m_Name: CamPivot 218 | m_TagString: Untagged 219 | m_Icon: {fileID: 0} 220 | m_NavMeshLayer: 0 221 | m_StaticEditorFlags: 0 222 | m_IsActive: 1 223 | --- !u!4 &1431333937 224 | Transform: 225 | m_ObjectHideFlags: 0 226 | m_CorrespondingSourceObject: {fileID: 0} 227 | m_PrefabInstance: {fileID: 0} 228 | m_PrefabAsset: {fileID: 0} 229 | m_GameObject: {fileID: 1431333936} 230 | m_LocalRotation: {x: 0.2588191, y: 0, z: 0, w: 0.9659258} 231 | m_LocalPosition: {x: 0, y: 0, z: 0} 232 | m_LocalScale: {x: 1, y: 1, z: 1} 233 | m_Children: 234 | - {fileID: 335347786} 235 | m_Father: {fileID: 0} 236 | m_RootOrder: 1 237 | m_LocalEulerAnglesHint: {x: 30, y: 0, z: 0} 238 | --- !u!1 &1563837377 239 | GameObject: 240 | m_ObjectHideFlags: 0 241 | m_CorrespondingSourceObject: {fileID: 0} 242 | m_PrefabInstance: {fileID: 0} 243 | m_PrefabAsset: {fileID: 0} 244 | serializedVersion: 6 245 | m_Component: 246 | - component: {fileID: 1563837381} 247 | - component: {fileID: 1563837380} 248 | - component: {fileID: 1563837379} 249 | - component: {fileID: 1563837378} 250 | m_Layer: 0 251 | m_Name: Floor 252 | m_TagString: Untagged 253 | m_Icon: {fileID: 0} 254 | m_NavMeshLayer: 0 255 | m_StaticEditorFlags: 0 256 | m_IsActive: 1 257 | --- !u!64 &1563837378 258 | MeshCollider: 259 | m_ObjectHideFlags: 0 260 | m_CorrespondingSourceObject: {fileID: 0} 261 | m_PrefabInstance: {fileID: 0} 262 | m_PrefabAsset: {fileID: 0} 263 | m_GameObject: {fileID: 1563837377} 264 | m_Material: {fileID: 0} 265 | m_IsTrigger: 0 266 | m_Enabled: 1 267 | serializedVersion: 4 268 | m_Convex: 0 269 | m_CookingOptions: 30 270 | m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} 271 | --- !u!23 &1563837379 272 | MeshRenderer: 273 | m_ObjectHideFlags: 0 274 | m_CorrespondingSourceObject: {fileID: 0} 275 | m_PrefabInstance: {fileID: 0} 276 | m_PrefabAsset: {fileID: 0} 277 | m_GameObject: {fileID: 1563837377} 278 | m_Enabled: 1 279 | m_CastShadows: 1 280 | m_ReceiveShadows: 1 281 | m_DynamicOccludee: 1 282 | m_MotionVectors: 1 283 | m_LightProbeUsage: 1 284 | m_ReflectionProbeUsage: 1 285 | m_RayTracingMode: 2 286 | m_RenderingLayerMask: 1 287 | m_RendererPriority: 0 288 | m_Materials: 289 | - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} 290 | m_StaticBatchInfo: 291 | firstSubMesh: 0 292 | subMeshCount: 0 293 | m_StaticBatchRoot: {fileID: 0} 294 | m_ProbeAnchor: {fileID: 0} 295 | m_LightProbeVolumeOverride: {fileID: 0} 296 | m_ScaleInLightmap: 1 297 | m_ReceiveGI: 1 298 | m_PreserveUVs: 0 299 | m_IgnoreNormalsForChartDetection: 0 300 | m_ImportantGI: 0 301 | m_StitchLightmapSeams: 1 302 | m_SelectedEditorRenderState: 3 303 | m_MinimumChartSize: 4 304 | m_AutoUVMaxDistance: 0.5 305 | m_AutoUVMaxAngle: 89 306 | m_LightmapParameters: {fileID: 0} 307 | m_SortingLayerID: 0 308 | m_SortingLayer: 0 309 | m_SortingOrder: 0 310 | --- !u!33 &1563837380 311 | MeshFilter: 312 | m_ObjectHideFlags: 0 313 | m_CorrespondingSourceObject: {fileID: 0} 314 | m_PrefabInstance: {fileID: 0} 315 | m_PrefabAsset: {fileID: 0} 316 | m_GameObject: {fileID: 1563837377} 317 | m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} 318 | --- !u!4 &1563837381 319 | Transform: 320 | m_ObjectHideFlags: 0 321 | m_CorrespondingSourceObject: {fileID: 0} 322 | m_PrefabInstance: {fileID: 0} 323 | m_PrefabAsset: {fileID: 0} 324 | m_GameObject: {fileID: 1563837377} 325 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 326 | m_LocalPosition: {x: 0, y: -1, z: 0} 327 | m_LocalScale: {x: 1, y: 1, z: 1} 328 | m_Children: [] 329 | m_Father: {fileID: 0} 330 | m_RootOrder: 2 331 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 332 | --- !u!1 &1876863014 333 | GameObject: 334 | m_ObjectHideFlags: 0 335 | m_CorrespondingSourceObject: {fileID: 0} 336 | m_PrefabInstance: {fileID: 0} 337 | m_PrefabAsset: {fileID: 0} 338 | serializedVersion: 6 339 | m_Component: 340 | - component: {fileID: 1876863016} 341 | - component: {fileID: 1876863015} 342 | m_Layer: 0 343 | m_Name: Directional Light 344 | m_TagString: Untagged 345 | m_Icon: {fileID: 0} 346 | m_NavMeshLayer: 0 347 | m_StaticEditorFlags: 0 348 | m_IsActive: 1 349 | --- !u!108 &1876863015 350 | Light: 351 | m_ObjectHideFlags: 0 352 | m_CorrespondingSourceObject: {fileID: 0} 353 | m_PrefabInstance: {fileID: 0} 354 | m_PrefabAsset: {fileID: 0} 355 | m_GameObject: {fileID: 1876863014} 356 | m_Enabled: 1 357 | serializedVersion: 10 358 | m_Type: 1 359 | m_Shape: 0 360 | m_Color: {r: 1, g: 1, b: 1, a: 1} 361 | m_Intensity: 1 362 | m_Range: 10 363 | m_SpotAngle: 30 364 | m_InnerSpotAngle: 21.80208 365 | m_CookieSize: 10 366 | m_Shadows: 367 | m_Type: 0 368 | m_Resolution: -1 369 | m_CustomResolution: -1 370 | m_Strength: 1 371 | m_Bias: 0.05 372 | m_NormalBias: 0.4 373 | m_NearPlane: 0.2 374 | m_CullingMatrixOverride: 375 | e00: 1 376 | e01: 0 377 | e02: 0 378 | e03: 0 379 | e10: 0 380 | e11: 1 381 | e12: 0 382 | e13: 0 383 | e20: 0 384 | e21: 0 385 | e22: 1 386 | e23: 0 387 | e30: 0 388 | e31: 0 389 | e32: 0 390 | e33: 1 391 | m_UseCullingMatrixOverride: 0 392 | m_Cookie: {fileID: 0} 393 | m_DrawHalo: 0 394 | m_Flare: {fileID: 0} 395 | m_RenderMode: 0 396 | m_CullingMask: 397 | serializedVersion: 2 398 | m_Bits: 4294967295 399 | m_RenderingLayerMask: 1 400 | m_Lightmapping: 4 401 | m_LightShadowCasterMode: 0 402 | m_AreaSize: {x: 1, y: 1} 403 | m_BounceIntensity: 1 404 | m_ColorTemperature: 6570 405 | m_UseColorTemperature: 0 406 | m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} 407 | m_UseBoundingSphereOverride: 0 408 | m_ShadowRadius: 0 409 | m_ShadowAngle: 0 410 | --- !u!4 &1876863016 411 | Transform: 412 | m_ObjectHideFlags: 0 413 | m_CorrespondingSourceObject: {fileID: 0} 414 | m_PrefabInstance: {fileID: 0} 415 | m_PrefabAsset: {fileID: 0} 416 | m_GameObject: {fileID: 1876863014} 417 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} 418 | m_LocalPosition: {x: 0, y: 0, z: 0} 419 | m_LocalScale: {x: 1, y: 1, z: 1} 420 | m_Children: [] 421 | m_Father: {fileID: 0} 422 | m_RootOrder: 0 423 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} 424 | --- !u!1 &1979347781 425 | GameObject: 426 | m_ObjectHideFlags: 0 427 | m_CorrespondingSourceObject: {fileID: 0} 428 | m_PrefabInstance: {fileID: 0} 429 | m_PrefabAsset: {fileID: 0} 430 | serializedVersion: 6 431 | m_Component: 432 | - component: {fileID: 1979347783} 433 | - component: {fileID: 1979347782} 434 | m_Layer: 0 435 | m_Name: ExampleAdvanced 436 | m_TagString: Untagged 437 | m_Icon: {fileID: 0} 438 | m_NavMeshLayer: 0 439 | m_StaticEditorFlags: 0 440 | m_IsActive: 1 441 | --- !u!114 &1979347782 442 | MonoBehaviour: 443 | m_ObjectHideFlags: 0 444 | m_CorrespondingSourceObject: {fileID: 0} 445 | m_PrefabInstance: {fileID: 0} 446 | m_PrefabAsset: {fileID: 0} 447 | m_GameObject: {fileID: 1979347781} 448 | m_Enabled: 1 449 | m_EditorHideFlags: 0 450 | m_Script: {fileID: 11500000, guid: c086227322664a1ab09daecc44f8e5fa, type: 3} 451 | m_Name: 452 | m_EditorClassIdentifier: 453 | prefab: {fileID: 2663155548185288521, guid: 8f65e2077557e2a48bb201a371e5d29b, type: 3} 454 | roundTime: 10 455 | --- !u!4 &1979347783 456 | Transform: 457 | m_ObjectHideFlags: 0 458 | m_CorrespondingSourceObject: {fileID: 0} 459 | m_PrefabInstance: {fileID: 0} 460 | m_PrefabAsset: {fileID: 0} 461 | m_GameObject: {fileID: 1979347781} 462 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 463 | m_LocalPosition: {x: 0, y: 0, z: 0} 464 | m_LocalScale: {x: 1, y: 1, z: 1} 465 | m_Children: [] 466 | m_Father: {fileID: 0} 467 | m_RootOrder: 3 468 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 469 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/StateMachine_Advanced.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fa60728e35284674e88aa2ae6df84576 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/StateMachine_Basic.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.2, g: 0.2, b: 0.2, a: 1} 24 | m_AmbientEquatorColor: {r: 0.2, g: 0.2, b: 0.2, a: 1} 25 | m_AmbientGroundColor: {r: 0.2, g: 0.2, b: 0.2, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 3 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &4 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 1 59 | m_BakeResolution: 50 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 0 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 0 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 1024 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 1 75 | m_BakeBackend: 0 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 500 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 500 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 0 83 | m_PVRDenoiserTypeDirect: 0 84 | m_PVRDenoiserTypeIndirect: 0 85 | m_PVRDenoiserTypeAO: 0 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 0 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_UseShadowmask: 0 102 | --- !u!196 &5 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666666 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | debug: 122 | m_Flags: 0 123 | m_NavMeshData: {fileID: 0} 124 | --- !u!1 &335347781 125 | GameObject: 126 | m_ObjectHideFlags: 0 127 | m_CorrespondingSourceObject: {fileID: 0} 128 | m_PrefabInstance: {fileID: 0} 129 | m_PrefabAsset: {fileID: 0} 130 | serializedVersion: 6 131 | m_Component: 132 | - component: {fileID: 335347786} 133 | - component: {fileID: 335347785} 134 | - component: {fileID: 335347782} 135 | m_Layer: 0 136 | m_Name: Main Camera 137 | m_TagString: MainCamera 138 | m_Icon: {fileID: 0} 139 | m_NavMeshLayer: 0 140 | m_StaticEditorFlags: 0 141 | m_IsActive: 1 142 | --- !u!81 &335347782 143 | AudioListener: 144 | m_ObjectHideFlags: 0 145 | m_CorrespondingSourceObject: {fileID: 0} 146 | m_PrefabInstance: {fileID: 0} 147 | m_PrefabAsset: {fileID: 0} 148 | m_GameObject: {fileID: 335347781} 149 | m_Enabled: 1 150 | --- !u!20 &335347785 151 | Camera: 152 | m_ObjectHideFlags: 0 153 | m_CorrespondingSourceObject: {fileID: 0} 154 | m_PrefabInstance: {fileID: 0} 155 | m_PrefabAsset: {fileID: 0} 156 | m_GameObject: {fileID: 335347781} 157 | m_Enabled: 1 158 | serializedVersion: 2 159 | m_ClearFlags: 1 160 | m_BackGroundColor: {r: 0.2519135, g: 0.28969136, b: 0.3490566, a: 0.019607844} 161 | m_projectionMatrixMode: 1 162 | m_GateFitMode: 2 163 | m_FOVAxisMode: 0 164 | m_SensorSize: {x: 36, y: 24} 165 | m_LensShift: {x: 0, y: 0} 166 | m_FocalLength: 50 167 | m_NormalizedViewPortRect: 168 | serializedVersion: 2 169 | x: 0 170 | y: 0 171 | width: 1 172 | height: 1 173 | near clip plane: 0.3 174 | far clip plane: 1000 175 | field of view: 60 176 | orthographic: 0 177 | orthographic size: 5 178 | m_Depth: -1 179 | m_CullingMask: 180 | serializedVersion: 2 181 | m_Bits: 4294967295 182 | m_RenderingPath: -1 183 | m_TargetTexture: {fileID: 0} 184 | m_TargetDisplay: 0 185 | m_TargetEye: 3 186 | m_HDR: 0 187 | m_AllowMSAA: 1 188 | m_AllowDynamicResolution: 0 189 | m_ForceIntoRT: 0 190 | m_OcclusionCulling: 1 191 | m_StereoConvergence: 10 192 | m_StereoSeparation: 0.022 193 | --- !u!4 &335347786 194 | Transform: 195 | m_ObjectHideFlags: 0 196 | m_CorrespondingSourceObject: {fileID: 0} 197 | m_PrefabInstance: {fileID: 0} 198 | m_PrefabAsset: {fileID: 0} 199 | m_GameObject: {fileID: 335347781} 200 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 201 | m_LocalPosition: {x: 0, y: 1, z: -10} 202 | m_LocalScale: {x: 1, y: 1, z: 1} 203 | m_Children: [] 204 | m_Father: {fileID: 0} 205 | m_RootOrder: 1 206 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 207 | --- !u!1 &1979347781 208 | GameObject: 209 | m_ObjectHideFlags: 0 210 | m_CorrespondingSourceObject: {fileID: 0} 211 | m_PrefabInstance: {fileID: 0} 212 | m_PrefabAsset: {fileID: 0} 213 | serializedVersion: 6 214 | m_Component: 215 | - component: {fileID: 1979347783} 216 | - component: {fileID: 1979347782} 217 | - component: {fileID: 1979347784} 218 | m_Layer: 0 219 | m_Name: ExampleBasic 220 | m_TagString: Untagged 221 | m_Icon: {fileID: 0} 222 | m_NavMeshLayer: 0 223 | m_StaticEditorFlags: 0 224 | m_IsActive: 1 225 | --- !u!114 &1979347782 226 | MonoBehaviour: 227 | m_ObjectHideFlags: 0 228 | m_CorrespondingSourceObject: {fileID: 0} 229 | m_PrefabInstance: {fileID: 0} 230 | m_PrefabAsset: {fileID: 0} 231 | m_GameObject: {fileID: 1979347781} 232 | m_Enabled: 1 233 | m_EditorHideFlags: 0 234 | m_Script: {fileID: 11500000, guid: e1b8c2ce0ae416a4ebf4865c20d2d12e, type: 3} 235 | m_Name: 236 | m_EditorClassIdentifier: 237 | health: 100 238 | damage: 20 239 | --- !u!4 &1979347783 240 | Transform: 241 | m_ObjectHideFlags: 0 242 | m_CorrespondingSourceObject: {fileID: 0} 243 | m_PrefabInstance: {fileID: 0} 244 | m_PrefabAsset: {fileID: 0} 245 | m_GameObject: {fileID: 1979347781} 246 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 247 | m_LocalPosition: {x: 0, y: 0, z: 0} 248 | m_LocalScale: {x: 1, y: 1, z: 1} 249 | m_Children: [] 250 | m_Father: {fileID: 0} 251 | m_RootOrder: 0 252 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 253 | --- !u!114 &1979347784 254 | MonoBehaviour: 255 | m_ObjectHideFlags: 0 256 | m_CorrespondingSourceObject: {fileID: 0} 257 | m_PrefabInstance: {fileID: 0} 258 | m_PrefabAsset: {fileID: 0} 259 | m_GameObject: {fileID: 1979347781} 260 | m_Enabled: 1 261 | m_EditorHideFlags: 0 262 | m_Script: {fileID: 11500000, guid: a57cafd734b9e8d4da74fd1b24e6107e, type: 3} 263 | m_Name: 264 | m_EditorClassIdentifier: 265 | interval: 1.2 266 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/StateMachine_Basic.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 55303e058e1539a40b0effa20cab4988 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/StressTest.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_UseShadowmask: 1 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | debug: 122 | m_Flags: 0 123 | m_NavMeshData: {fileID: 0} 124 | --- !u!1 &741488261 125 | GameObject: 126 | m_ObjectHideFlags: 0 127 | m_CorrespondingSourceObject: {fileID: 0} 128 | m_PrefabInstance: {fileID: 0} 129 | m_PrefabAsset: {fileID: 0} 130 | serializedVersion: 6 131 | m_Component: 132 | - component: {fileID: 741488263} 133 | - component: {fileID: 741488262} 134 | m_Layer: 0 135 | m_Name: Directional Light 136 | m_TagString: Untagged 137 | m_Icon: {fileID: 0} 138 | m_NavMeshLayer: 0 139 | m_StaticEditorFlags: 0 140 | m_IsActive: 1 141 | --- !u!108 &741488262 142 | Light: 143 | m_ObjectHideFlags: 0 144 | m_CorrespondingSourceObject: {fileID: 0} 145 | m_PrefabInstance: {fileID: 0} 146 | m_PrefabAsset: {fileID: 0} 147 | m_GameObject: {fileID: 741488261} 148 | m_Enabled: 1 149 | serializedVersion: 10 150 | m_Type: 1 151 | m_Shape: 0 152 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} 153 | m_Intensity: 1 154 | m_Range: 10 155 | m_SpotAngle: 30 156 | m_InnerSpotAngle: 21.80208 157 | m_CookieSize: 10 158 | m_Shadows: 159 | m_Type: 2 160 | m_Resolution: -1 161 | m_CustomResolution: -1 162 | m_Strength: 1 163 | m_Bias: 0.05 164 | m_NormalBias: 0.4 165 | m_NearPlane: 0.2 166 | m_CullingMatrixOverride: 167 | e00: 1 168 | e01: 0 169 | e02: 0 170 | e03: 0 171 | e10: 0 172 | e11: 1 173 | e12: 0 174 | e13: 0 175 | e20: 0 176 | e21: 0 177 | e22: 1 178 | e23: 0 179 | e30: 0 180 | e31: 0 181 | e32: 0 182 | e33: 1 183 | m_UseCullingMatrixOverride: 0 184 | m_Cookie: {fileID: 0} 185 | m_DrawHalo: 0 186 | m_Flare: {fileID: 0} 187 | m_RenderMode: 0 188 | m_CullingMask: 189 | serializedVersion: 2 190 | m_Bits: 4294967295 191 | m_RenderingLayerMask: 1 192 | m_Lightmapping: 4 193 | m_LightShadowCasterMode: 0 194 | m_AreaSize: {x: 1, y: 1} 195 | m_BounceIntensity: 1 196 | m_ColorTemperature: 6570 197 | m_UseColorTemperature: 0 198 | m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} 199 | m_UseBoundingSphereOverride: 0 200 | m_ShadowRadius: 0 201 | m_ShadowAngle: 0 202 | --- !u!4 &741488263 203 | Transform: 204 | m_ObjectHideFlags: 0 205 | m_CorrespondingSourceObject: {fileID: 0} 206 | m_PrefabInstance: {fileID: 0} 207 | m_PrefabAsset: {fileID: 0} 208 | m_GameObject: {fileID: 741488261} 209 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} 210 | m_LocalPosition: {x: 0, y: 3, z: 0} 211 | m_LocalScale: {x: 1, y: 1, z: 1} 212 | m_Children: [] 213 | m_Father: {fileID: 0} 214 | m_RootOrder: 1 215 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} 216 | --- !u!1 &1532717787 217 | GameObject: 218 | m_ObjectHideFlags: 0 219 | m_CorrespondingSourceObject: {fileID: 0} 220 | m_PrefabInstance: {fileID: 0} 221 | m_PrefabAsset: {fileID: 0} 222 | serializedVersion: 6 223 | m_Component: 224 | - component: {fileID: 1532717790} 225 | - component: {fileID: 1532717789} 226 | - component: {fileID: 1532717788} 227 | m_Layer: 0 228 | m_Name: Main Camera 229 | m_TagString: MainCamera 230 | m_Icon: {fileID: 0} 231 | m_NavMeshLayer: 0 232 | m_StaticEditorFlags: 0 233 | m_IsActive: 1 234 | --- !u!81 &1532717788 235 | AudioListener: 236 | m_ObjectHideFlags: 0 237 | m_CorrespondingSourceObject: {fileID: 0} 238 | m_PrefabInstance: {fileID: 0} 239 | m_PrefabAsset: {fileID: 0} 240 | m_GameObject: {fileID: 1532717787} 241 | m_Enabled: 1 242 | --- !u!20 &1532717789 243 | Camera: 244 | m_ObjectHideFlags: 0 245 | m_CorrespondingSourceObject: {fileID: 0} 246 | m_PrefabInstance: {fileID: 0} 247 | m_PrefabAsset: {fileID: 0} 248 | m_GameObject: {fileID: 1532717787} 249 | m_Enabled: 1 250 | serializedVersion: 2 251 | m_ClearFlags: 1 252 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 253 | m_projectionMatrixMode: 1 254 | m_GateFitMode: 2 255 | m_FOVAxisMode: 0 256 | m_SensorSize: {x: 36, y: 24} 257 | m_LensShift: {x: 0, y: 0} 258 | m_FocalLength: 50 259 | m_NormalizedViewPortRect: 260 | serializedVersion: 2 261 | x: 0 262 | y: 0 263 | width: 1 264 | height: 1 265 | near clip plane: 0.3 266 | far clip plane: 1000 267 | field of view: 60 268 | orthographic: 0 269 | orthographic size: 5 270 | m_Depth: -1 271 | m_CullingMask: 272 | serializedVersion: 2 273 | m_Bits: 4294967295 274 | m_RenderingPath: -1 275 | m_TargetTexture: {fileID: 0} 276 | m_TargetDisplay: 0 277 | m_TargetEye: 3 278 | m_HDR: 1 279 | m_AllowMSAA: 1 280 | m_AllowDynamicResolution: 0 281 | m_ForceIntoRT: 0 282 | m_OcclusionCulling: 1 283 | m_StereoConvergence: 10 284 | m_StereoSeparation: 0.022 285 | --- !u!4 &1532717790 286 | Transform: 287 | m_ObjectHideFlags: 0 288 | m_CorrespondingSourceObject: {fileID: 0} 289 | m_PrefabInstance: {fileID: 0} 290 | m_PrefabAsset: {fileID: 0} 291 | m_GameObject: {fileID: 1532717787} 292 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 293 | m_LocalPosition: {x: 0, y: 1, z: -10} 294 | m_LocalScale: {x: 1, y: 1, z: 1} 295 | m_Children: [] 296 | m_Father: {fileID: 0} 297 | m_RootOrder: 0 298 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 299 | --- !u!1 &1882005350 300 | GameObject: 301 | m_ObjectHideFlags: 0 302 | m_CorrespondingSourceObject: {fileID: 0} 303 | m_PrefabInstance: {fileID: 0} 304 | m_PrefabAsset: {fileID: 0} 305 | serializedVersion: 6 306 | m_Component: 307 | - component: {fileID: 1882005352} 308 | - component: {fileID: 1882005351} 309 | m_Layer: 0 310 | m_Name: StressTest 311 | m_TagString: Untagged 312 | m_Icon: {fileID: 0} 313 | m_NavMeshLayer: 0 314 | m_StaticEditorFlags: 0 315 | m_IsActive: 1 316 | --- !u!114 &1882005351 317 | MonoBehaviour: 318 | m_ObjectHideFlags: 0 319 | m_CorrespondingSourceObject: {fileID: 0} 320 | m_PrefabInstance: {fileID: 0} 321 | m_PrefabAsset: {fileID: 0} 322 | m_GameObject: {fileID: 1882005350} 323 | m_Enabled: 1 324 | m_EditorHideFlags: 0 325 | m_Script: {fileID: 11500000, guid: 5feefe5bbb45416ca0f4953ecfff49da, type: 3} 326 | m_Name: 327 | m_EditorClassIdentifier: 328 | --- !u!4 &1882005352 329 | Transform: 330 | m_ObjectHideFlags: 0 331 | m_CorrespondingSourceObject: {fileID: 0} 332 | m_PrefabInstance: {fileID: 0} 333 | m_PrefabAsset: {fileID: 0} 334 | m_GameObject: {fileID: 1882005350} 335 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 336 | m_LocalPosition: {x: 0, y: 0, z: 0} 337 | m_LocalScale: {x: 1, y: 1, z: 1} 338 | m_Children: [] 339 | m_Father: {fileID: 0} 340 | m_RootOrder: 2 341 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 342 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Samples/StressTest.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 838eb45cb78a5f94eaf4f72ef961a72f 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9bb6984bd108d8f4f8418c4f37e0ca0d 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9c8afd02806bc1d4cab6182962b1ccc4 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/MonsterLove.StateMachine.Tests.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "EditorTests", 3 | "references": [ 4 | "MonsterLove.StateMachine.Runtime", 5 | "MonsterLove.StateMachine.Tests.Runtime", 6 | "UnityEngine.TestRunner", 7 | "UnityEditor.TestRunner" 8 | ], 9 | "includePlatforms": [ 10 | "Editor" 11 | ], 12 | "excludePlatforms": [], 13 | "allowUnsafeCode": false, 14 | "overrideReferences": true, 15 | "precompiledReferences": [ 16 | "nunit.framework.dll" 17 | ], 18 | "autoReferenced": false, 19 | "defineConstraints": [ 20 | "UNITY_INCLUDE_TESTS" 21 | ], 22 | "versionDefines": [], 23 | "noEngineReferences": false 24 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/MonsterLove.StateMachine.Tests.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7a05261385aac3941b3b93eaf9a30bed 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestBasicTransitions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MonsterLove.StateMachine; 3 | using NUnit.Framework; 4 | using UnityEngine; 5 | using UnityEditor; 6 | using System.Collections; 7 | using Object = UnityEngine.Object; 8 | 9 | [TestFixture] 10 | [Category("State Machine Tests")] 11 | internal class TestBasicTransitions 12 | { 13 | public enum States 14 | { 15 | One, 16 | Two, 17 | Three, 18 | } 19 | 20 | private GameObject go; 21 | private ClassWithBasicStates behaviour; 22 | private StateMachineRunner engine; 23 | private StateMachine fsm; 24 | 25 | [SetUp] 26 | public void Init() 27 | { 28 | go = new GameObject("stateTest"); 29 | behaviour = go.AddComponent(); 30 | engine = go.AddComponent(); 31 | } 32 | 33 | [TearDown] 34 | public void Kill() 35 | { 36 | Object.DestroyImmediate(go); 37 | } 38 | 39 | [Test] 40 | public void NoTransitions() 41 | { 42 | fsm = engine.Initialize(behaviour); 43 | 44 | //Goes to start state by default; 45 | Assert.AreEqual(0, behaviour.oneStats.enterCount); 46 | Assert.AreEqual(0, behaviour.oneStats.updateCount); 47 | Assert.AreEqual(0, behaviour.oneStats.lateUpdateCount); 48 | Assert.AreEqual(0, behaviour.oneStats.exitCount); 49 | Assert.AreEqual(0, behaviour.oneStats.finallyCount); 50 | 51 | Assert.AreEqual(0, behaviour.twoStats.enterCount); 52 | Assert.AreEqual(0, behaviour.twoStats.updateCount); 53 | Assert.AreEqual(0, behaviour.twoStats.lateUpdateCount); 54 | Assert.AreEqual(0, behaviour.twoStats.exitCount); 55 | Assert.AreEqual(0, behaviour.twoStats.finallyCount); 56 | 57 | Assert.AreEqual(0, behaviour.threeStats.enterCount); 58 | Assert.AreEqual(0, behaviour.threeStats.updateCount); 59 | Assert.AreEqual(0, behaviour.threeStats.lateUpdateCount); 60 | Assert.AreEqual(0, behaviour.threeStats.exitCount); 61 | Assert.AreEqual(0, behaviour.threeStats.finallyCount); 62 | } 63 | 64 | 65 | [Test] 66 | public void InitialTransition() 67 | { 68 | fsm = engine.Initialize(behaviour, States.One); 69 | fsm.ChangeState(States.Two); 70 | 71 | Assert.AreEqual(1, behaviour.oneStats.enterCount); 72 | Assert.AreEqual(0, behaviour.oneStats.updateCount); 73 | Assert.AreEqual(0, behaviour.oneStats.lateUpdateCount); 74 | Assert.AreEqual(1, behaviour.oneStats.exitCount); 75 | Assert.AreEqual(1, behaviour.oneStats.finallyCount); 76 | 77 | Assert.AreEqual(1, behaviour.twoStats.enterCount); 78 | Assert.AreEqual(0, behaviour.twoStats.updateCount); 79 | Assert.AreEqual(0, behaviour.twoStats.lateUpdateCount); 80 | Assert.AreEqual(0, behaviour.twoStats.exitCount); 81 | Assert.AreEqual(0, behaviour.twoStats.finallyCount); 82 | 83 | Assert.AreEqual(0, behaviour.threeStats.enterCount); 84 | Assert.AreEqual(0, behaviour.threeStats.updateCount); 85 | Assert.AreEqual(0, behaviour.threeStats.lateUpdateCount); 86 | Assert.AreEqual(0, behaviour.threeStats.exitCount); 87 | Assert.AreEqual(0, behaviour.threeStats.finallyCount); 88 | } 89 | 90 | 91 | [Test] 92 | public void IgnoreMultipleTransitions() 93 | { 94 | fsm = engine.Initialize(behaviour, States.One); 95 | fsm.ChangeState(States.Two); 96 | fsm.ChangeState(States.Two); 97 | 98 | Assert.AreEqual(1, behaviour.oneStats.enterCount); 99 | Assert.AreEqual(0, behaviour.oneStats.updateCount); 100 | Assert.AreEqual(0, behaviour.oneStats.lateUpdateCount); 101 | Assert.AreEqual(1, behaviour.oneStats.exitCount); 102 | Assert.AreEqual(1, behaviour.oneStats.finallyCount); 103 | 104 | Assert.AreEqual(1, behaviour.twoStats.enterCount); 105 | Assert.AreEqual(0, behaviour.twoStats.updateCount); 106 | Assert.AreEqual(0, behaviour.twoStats.lateUpdateCount); 107 | Assert.AreEqual(0, behaviour.twoStats.exitCount); 108 | Assert.AreEqual(0, behaviour.twoStats.finallyCount); 109 | 110 | Assert.AreEqual(0, behaviour.threeStats.enterCount); 111 | Assert.AreEqual(0, behaviour.threeStats.updateCount); 112 | Assert.AreEqual(0, behaviour.threeStats.lateUpdateCount); 113 | Assert.AreEqual(0, behaviour.threeStats.exitCount); 114 | Assert.AreEqual(0, behaviour.threeStats.finallyCount); 115 | 116 | fsm.reenter = true; 117 | 118 | fsm.ChangeState(States.Three); 119 | fsm.ChangeState(States.Three); 120 | 121 | Assert.AreEqual(1, behaviour.twoStats.enterCount); 122 | Assert.AreEqual(0, behaviour.twoStats.updateCount); 123 | Assert.AreEqual(0, behaviour.twoStats.lateUpdateCount); 124 | Assert.AreEqual(1, behaviour.twoStats.exitCount); 125 | Assert.AreEqual(1, behaviour.twoStats.finallyCount); 126 | 127 | Assert.AreEqual(2, behaviour.threeStats.enterCount); 128 | Assert.AreEqual(0, behaviour.threeStats.updateCount); 129 | Assert.AreEqual(0, behaviour.threeStats.lateUpdateCount); 130 | Assert.AreEqual(1, behaviour.threeStats.exitCount); 131 | Assert.AreEqual(1, behaviour.threeStats.finallyCount); 132 | 133 | 134 | } 135 | 136 | [Test] 137 | public void SpecifiedDefault() 138 | { 139 | fsm = engine.Initialize(behaviour, States.Two); 140 | 141 | Assert.AreEqual(0, behaviour.oneStats.enterCount); 142 | Assert.AreEqual(0, behaviour.oneStats.updateCount); 143 | Assert.AreEqual(0, behaviour.oneStats.lateUpdateCount); 144 | Assert.AreEqual(0, behaviour.oneStats.exitCount); 145 | Assert.AreEqual(0, behaviour.oneStats.finallyCount); 146 | 147 | Assert.AreEqual(1, behaviour.twoStats.enterCount); 148 | Assert.AreEqual(0, behaviour.twoStats.updateCount); 149 | Assert.AreEqual(0, behaviour.twoStats.lateUpdateCount); 150 | Assert.AreEqual(0, behaviour.twoStats.exitCount); 151 | Assert.AreEqual(0, behaviour.twoStats.finallyCount); 152 | 153 | Assert.AreEqual(0, behaviour.threeStats.enterCount); 154 | Assert.AreEqual(0, behaviour.threeStats.updateCount); 155 | Assert.AreEqual(0, behaviour.threeStats.lateUpdateCount); 156 | Assert.AreEqual(0, behaviour.threeStats.exitCount); 157 | Assert.AreEqual(0, behaviour.threeStats.finallyCount); 158 | 159 | } 160 | 161 | [Test] 162 | public void MultipleTransitions() 163 | { 164 | fsm = engine.Initialize(behaviour, States.One); 165 | 166 | fsm.ChangeState(States.One); 167 | fsm.ChangeState(States.Two); 168 | fsm.ChangeState(States.Three); 169 | 170 | Assert.AreEqual(1, behaviour.oneStats.enterCount); 171 | Assert.AreEqual(0, behaviour.oneStats.updateCount); 172 | Assert.AreEqual(0, behaviour.oneStats.lateUpdateCount); 173 | Assert.AreEqual(1, behaviour.oneStats.exitCount); 174 | Assert.AreEqual(1, behaviour.oneStats.finallyCount); 175 | 176 | Assert.AreEqual(1, behaviour.twoStats.enterCount); 177 | Assert.AreEqual(0, behaviour.twoStats.updateCount); 178 | Assert.AreEqual(0, behaviour.twoStats.lateUpdateCount); 179 | Assert.AreEqual(1, behaviour.twoStats.exitCount); 180 | Assert.AreEqual(1, behaviour.twoStats.finallyCount); 181 | 182 | Assert.AreEqual(1, behaviour.threeStats.enterCount); 183 | Assert.AreEqual(0, behaviour.threeStats.updateCount); 184 | Assert.AreEqual(0, behaviour.threeStats.lateUpdateCount); 185 | Assert.AreEqual(0, behaviour.threeStats.exitCount); 186 | Assert.AreEqual(0, behaviour.threeStats.finallyCount); 187 | 188 | } 189 | 190 | 191 | } 192 | 193 | 194 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestBasicTransitions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 899062ccff9246a4c8873c29a4ac6bf4 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestCachedDriver.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | using MonsterLove.StateMachine; 3 | using NUnit.Framework; 4 | using UnityEngine; 5 | 6 | /// This is an important test, enables subscription directly to driver objects 7 | /// Eg. button.OnClick.AddListener(fsm.Driver.Foo.Invoke) 8 | public class TestCachedDriver 9 | { 10 | public enum States 11 | { 12 | One, 13 | Two, 14 | Three, 15 | Four, 16 | } 17 | 18 | public class Driver 19 | { 20 | public StateEvent Foo; 21 | } 22 | 23 | private GameObject go; 24 | private StateClass behaviour; 25 | private StateMachine fsm; 26 | private Driver driver; 27 | 28 | [SetUp] 29 | public void Init() 30 | { 31 | go = new GameObject(); 32 | behaviour = go.AddComponent(); 33 | 34 | fsm = new StateMachine(behaviour); 35 | driver = fsm.Driver; 36 | } 37 | 38 | [TearDown] 39 | public void Kill() 40 | { 41 | Object.DestroyImmediate(go); 42 | } 43 | 44 | [Test] 45 | public void TestCachedDriverEvents() 46 | { 47 | fsm.ChangeState(States.One); 48 | 49 | driver.Foo.Invoke(); 50 | 51 | Assert.AreEqual(1, behaviour.oneFoo); 52 | Assert.AreEqual(0, behaviour.twoFoo); 53 | 54 | fsm.ChangeState(States.Two); 55 | 56 | driver.Foo.Invoke(); 57 | 58 | Assert.AreEqual(1, behaviour.oneFoo); 59 | Assert.AreEqual(1, behaviour.twoFoo); 60 | } 61 | 62 | private class StateClass : MonoBehaviour 63 | { 64 | public int oneEnter; 65 | public int oneFoo; 66 | public int oneExit; 67 | 68 | public int twoEnter; 69 | public int twoFoo; 70 | public int twoExit; 71 | 72 | void One_Enter() 73 | { 74 | //Debug.LogFormat("State:{0} Frame:{1}", "One Enter", Time.frameCount); 75 | oneEnter++; 76 | } 77 | 78 | void One_Foo() 79 | { 80 | //Debug.LogFormat("State:{0} Frame:{1}", "One Foo", Time.frameCount); 81 | oneFoo++; 82 | } 83 | 84 | void One_Exit() 85 | { 86 | //Debug.LogFormat("State:{0} Frame:{1}", "One Exit", Time.frameCount); 87 | oneExit++; 88 | } 89 | 90 | void Two_Enter() 91 | { 92 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Enter", Time.frameCount); 93 | twoEnter++; 94 | } 95 | 96 | void Two_Foo() 97 | { 98 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Foo", Time.frameCount); 99 | twoFoo++; 100 | } 101 | 102 | void Two_Exit() 103 | { 104 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Exit", Time.frameCount); 105 | twoExit++; 106 | } 107 | } 108 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestCachedDriver.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 597262340b854411b6859c314743cbfe 3 | timeCreated: 1568106780 -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestCustomDriver.cs: -------------------------------------------------------------------------------- 1 | using MonsterLove.StateMachine; 2 | using NUnit.Framework; 3 | using UnityEngine; 4 | 5 | public class TestCustomDriver 6 | { 7 | public enum States 8 | { 9 | One, 10 | Two, 11 | Three, 12 | Four, 13 | } 14 | 15 | public class Driver 16 | { 17 | public StateEvent Foo; 18 | public StateEvent Bar; 19 | public StateEvent Baz; 20 | } 21 | 22 | private GameObject go; 23 | private StateClass behaviour; 24 | private StateMachine fsm; 25 | 26 | [SetUp] 27 | public void Init() 28 | { 29 | go = new GameObject(); 30 | behaviour = go.AddComponent(); 31 | 32 | fsm = new StateMachine(behaviour); 33 | } 34 | 35 | [TearDown] 36 | public void Kill() 37 | { 38 | Object.DestroyImmediate(go); 39 | } 40 | 41 | [Test] 42 | public void TestDriverNotNull() 43 | { 44 | Assert.NotNull(fsm.Driver); 45 | } 46 | 47 | [Test] 48 | public void TestCustomEvents() 49 | { 50 | fsm.ChangeState(States.One); 51 | 52 | fsm.Driver.Foo.Invoke(); 53 | fsm.Driver.Bar.Invoke(5); 54 | fsm.Driver.Baz.Invoke(6, 7); 55 | 56 | Assert.AreEqual(1, behaviour.oneFoo); 57 | Assert.AreEqual(1, behaviour.oneBar); 58 | Assert.AreEqual(1, behaviour.oneBaz); 59 | Assert.AreEqual(5, behaviour.oneBarValue); 60 | Assert.AreEqual(6, behaviour.oneBazValueA); 61 | Assert.AreEqual(7, behaviour.oneBazValueB); 62 | 63 | Assert.AreEqual(0, behaviour.twoFoo); 64 | Assert.AreEqual(0, behaviour.twoBar); 65 | Assert.AreEqual(0, behaviour.twoBaz); 66 | Assert.AreEqual(0, behaviour.twoBarValue); 67 | Assert.AreEqual(0, behaviour.twoBazValueA); 68 | Assert.AreEqual(0, behaviour.twoBazValueB); 69 | 70 | fsm.ChangeState(States.Two); 71 | 72 | fsm.Driver.Foo.Invoke(); 73 | fsm.Driver.Bar.Invoke(8); 74 | fsm.Driver.Baz.Invoke(9, 10); 75 | 76 | Assert.AreEqual(1, behaviour.oneFoo); 77 | Assert.AreEqual(1, behaviour.oneBar); 78 | Assert.AreEqual(1, behaviour.oneBaz); 79 | Assert.AreEqual(5, behaviour.oneBarValue); 80 | Assert.AreEqual(6, behaviour.oneBazValueA); 81 | Assert.AreEqual(7, behaviour.oneBazValueB); 82 | 83 | Assert.AreEqual(1, behaviour.twoFoo); 84 | Assert.AreEqual(1, behaviour.twoBar); 85 | Assert.AreEqual(1, behaviour.twoBaz); 86 | Assert.AreEqual(8, behaviour.twoBarValue); 87 | Assert.AreEqual(9, behaviour.twoBazValueA); 88 | Assert.AreEqual(10, behaviour.twoBazValueB); 89 | } 90 | 91 | private class StateClass : MonoBehaviour 92 | { 93 | public int oneEnter; 94 | public int oneFoo; 95 | public int oneBar; 96 | public int oneBaz; 97 | public int oneExit; 98 | 99 | public int oneBarValue; 100 | public int oneBazValueA; 101 | public int oneBazValueB; 102 | 103 | public int twoEnter; 104 | public int twoFoo; 105 | public int twoBar; 106 | public int twoBaz; 107 | public int twoExit; 108 | 109 | public int twoBarValue; 110 | public int twoBazValueA; 111 | public int twoBazValueB; 112 | 113 | void One_Enter() 114 | { 115 | //Debug.LogFormat("State:{0} Frame:{1}", "One Enter", Time.frameCount); 116 | oneEnter++; 117 | } 118 | 119 | void One_Foo() 120 | { 121 | //Debug.LogFormat("State:{0} Frame:{1}", "One Foo", Time.frameCount); 122 | oneFoo++; 123 | } 124 | 125 | void One_Bar(int value) 126 | { 127 | //Debug.LogFormat("State:{0} Frame:{1}", "One Bar", Time.frameCount); 128 | oneBar++; 129 | oneBarValue = value; 130 | } 131 | 132 | void One_Baz(int valueA, int valueB) 133 | { 134 | //Debug.LogFormat("State:{0} Frame:{1}", "One Baz", Time.frameCount); 135 | oneBaz++; 136 | oneBazValueA = valueA; 137 | oneBazValueB = valueB; 138 | } 139 | 140 | void One_Exit() 141 | { 142 | //Debug.LogFormat("State:{0} Frame:{1}", "One Exit", Time.frameCount); 143 | oneExit++; 144 | } 145 | 146 | void Two_Enter() 147 | { 148 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Enter", Time.frameCount); 149 | twoEnter++; 150 | } 151 | 152 | void Two_Foo() 153 | { 154 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Foo", Time.frameCount); 155 | twoFoo++; 156 | } 157 | 158 | void Two_Bar(int value) 159 | { 160 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Bar", Time.frameCount); 161 | twoBar++; 162 | twoBarValue = value; 163 | } 164 | 165 | void Two_Baz(int valueA, int valueB) 166 | { 167 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Baz", Time.frameCount); 168 | twoBaz++; 169 | twoBazValueA = valueA; 170 | twoBazValueB = valueB; 171 | } 172 | 173 | void Two_Exit() 174 | { 175 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Exit", Time.frameCount); 176 | twoExit++; 177 | } 178 | } 179 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestCustomDriver.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9ac0e8e3b6264af6ad5122d174f3e4b5 3 | timeCreated: 1567780312 -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestDerivedFromSuperClass.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MonsterLove.StateMachine; 3 | using NUnit.Framework; 4 | using UnityEngine; 5 | using UnityEditor; 6 | using System.Collections; 7 | using Object = UnityEngine.Object; 8 | 9 | [TestFixture] 10 | [Category("State Machine Tests")] 11 | internal class TestDerivedFromSuperClass 12 | { 13 | public enum States 14 | { 15 | One, 16 | Two, 17 | Three, 18 | } 19 | 20 | private GameObject go; 21 | private ClassWithBasicStates behaviour; 22 | private StateMachineRunner engine; 23 | private StateMachine fsm; 24 | 25 | [SetUp] 26 | public void Init() 27 | { 28 | go = new GameObject("stateTest"); 29 | behaviour = go.AddComponent(); 30 | engine = go.AddComponent(); 31 | } 32 | 33 | [TearDown] 34 | public void Kill() 35 | { 36 | Object.DestroyImmediate(go); 37 | } 38 | 39 | [Test] 40 | public void InitialTransition() 41 | { 42 | fsm = engine.Initialize(behaviour, States.One); 43 | fsm.ChangeState(States.Two); 44 | 45 | //Test for when we want to include superclass methods 46 | Assert.AreEqual(1, behaviour.oneStats.enterCount); 47 | Assert.AreEqual(0, behaviour.oneStats.updateCount); 48 | Assert.AreEqual(0, behaviour.oneStats.lateUpdateCount); 49 | Assert.AreEqual(1, behaviour.oneStats.exitCount); 50 | Assert.AreEqual(1, behaviour.oneStats.finallyCount); 51 | 52 | Assert.AreEqual(1, behaviour.twoStats.enterCount); 53 | Assert.AreEqual(0, behaviour.twoStats.updateCount); 54 | Assert.AreEqual(0, behaviour.twoStats.lateUpdateCount); 55 | Assert.AreEqual(0, behaviour.twoStats.exitCount); 56 | Assert.AreEqual(0, behaviour.twoStats.finallyCount); 57 | } 58 | } 59 | 60 | 61 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestDerivedFromSuperClass.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 61f4fd153167fd343a371f18957007dc 3 | timeCreated: 1466595036 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestDisabledComponent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MonsterLove.StateMachine; 3 | using NUnit.Framework; 4 | using UnityEngine; 5 | using UnityEditor; 6 | using System.Collections; 7 | using Object = UnityEngine.Object; 8 | 9 | [TestFixture] 10 | [Category("State Machine Tests")] 11 | internal class TestDisabledComponent 12 | { 13 | public enum States 14 | { 15 | One, 16 | Two, 17 | Three, 18 | } 19 | 20 | private GameObject go; 21 | private ClassWithBasicStates behaviour; 22 | private StateMachineRunner engine; 23 | private StateMachine fsm; 24 | 25 | [SetUp] 26 | public void Init() 27 | { 28 | go = new GameObject("stateTest"); 29 | behaviour = go.AddComponent(); 30 | engine = go.AddComponent(); 31 | } 32 | 33 | [TearDown] 34 | public void Kill() 35 | { 36 | Object.DestroyImmediate(go); 37 | } 38 | 39 | [Test] 40 | public void InitialTransition() 41 | { 42 | fsm = engine.Initialize(behaviour, States.One); 43 | fsm.ChangeState(States.Two); 44 | 45 | Assert.AreEqual(1, behaviour.oneStats.enterCount); 46 | Assert.AreEqual(0, behaviour.oneStats.updateCount); 47 | Assert.AreEqual(0, behaviour.oneStats.lateUpdateCount); 48 | Assert.AreEqual(1, behaviour.oneStats.exitCount); 49 | Assert.AreEqual(1, behaviour.oneStats.finallyCount); 50 | 51 | Assert.AreEqual(1, behaviour.twoStats.enterCount); 52 | Assert.AreEqual(0, behaviour.twoStats.updateCount); 53 | Assert.AreEqual(0, behaviour.twoStats.lateUpdateCount); 54 | Assert.AreEqual(0, behaviour.twoStats.exitCount); 55 | Assert.AreEqual(0, behaviour.twoStats.finallyCount); 56 | 57 | Assert.AreEqual(0, behaviour.threeStats.enterCount); 58 | Assert.AreEqual(0, behaviour.threeStats.updateCount); 59 | Assert.AreEqual(0, behaviour.threeStats.lateUpdateCount); 60 | Assert.AreEqual(0, behaviour.threeStats.exitCount); 61 | Assert.AreEqual(0, behaviour.threeStats.finallyCount); 62 | 63 | behaviour.enabled = false; 64 | fsm.ChangeState(States.Three); 65 | 66 | Assert.AreEqual(1, behaviour.oneStats.enterCount); 67 | Assert.AreEqual(0, behaviour.oneStats.updateCount); 68 | Assert.AreEqual(0, behaviour.oneStats.lateUpdateCount); 69 | Assert.AreEqual(1, behaviour.oneStats.exitCount); 70 | Assert.AreEqual(1, behaviour.oneStats.finallyCount); 71 | 72 | Assert.AreEqual(1, behaviour.twoStats.enterCount); 73 | Assert.AreEqual(0, behaviour.twoStats.updateCount); 74 | Assert.AreEqual(0, behaviour.twoStats.lateUpdateCount); 75 | Assert.AreEqual(1, behaviour.twoStats.exitCount); 76 | Assert.AreEqual(1, behaviour.twoStats.finallyCount); 77 | 78 | Assert.AreEqual(1, behaviour.threeStats.enterCount); 79 | Assert.AreEqual(0, behaviour.threeStats.updateCount); 80 | Assert.AreEqual(0, behaviour.threeStats.lateUpdateCount); 81 | Assert.AreEqual(0, behaviour.threeStats.exitCount); 82 | Assert.AreEqual(0, behaviour.threeStats.finallyCount); 83 | 84 | 85 | } 86 | 87 | 88 | } 89 | 90 | 91 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestDisabledComponent.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ee524972135f5c140a4a5a973cd64ce7 3 | timeCreated: 1457610908 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestDriverLifecycle.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using MonsterLove.StateMachine; 3 | using NUnit.Framework; 4 | using UnityEditor; 5 | using UnityEngine; 6 | using UnityEngine.PlayerLoop; 7 | using UnityEngine.TestTools; 8 | 9 | public class TestDriverLifecycle 10 | { 11 | public enum States 12 | { 13 | One, 14 | Two, 15 | Three, 16 | Four, 17 | } 18 | 19 | public class Driver 20 | { 21 | public StateEvent Foo; 22 | } 23 | 24 | private GameObject go; 25 | private StateClass behaviour; 26 | private StateMachine fsm; 27 | 28 | [SetUp] 29 | public void Init() 30 | { 31 | go = new GameObject(); 32 | behaviour = go.AddComponent(); 33 | 34 | fsm = new StateMachine(behaviour); 35 | } 36 | 37 | [TearDown] 38 | public void Kill() 39 | { 40 | Object.DestroyImmediate(go); 41 | } 42 | 43 | [Test] 44 | public void TestDriverEventDoesntFireBeforeStateSet() 45 | { 46 | fsm.Driver.Foo.Invoke(); 47 | 48 | Assert.AreEqual(0, behaviour.oneFoo); 49 | 50 | fsm.ChangeState(States.One); 51 | 52 | fsm.Driver.Foo.Invoke(); 53 | 54 | Assert.AreEqual(1, behaviour.oneFoo); 55 | } 56 | 57 | private class StateClass : MonoBehaviour 58 | { 59 | public int oneEnter; 60 | public int oneFoo; 61 | public int oneBar; 62 | public int oneBaz; 63 | public int oneExit; 64 | 65 | public int oneBarValue; 66 | public int oneBazValueA; 67 | public int oneBazValueB; 68 | 69 | public int twoEnter; 70 | public int twoFoo; 71 | public int twoBar; 72 | public int twoBaz; 73 | public int twoExit; 74 | 75 | public int twoBarValue; 76 | public int twoBazValueA; 77 | public int twoBazValueB; 78 | 79 | void One_Enter() 80 | { 81 | //Debug.LogFormat("State:{0} Frame:{1}", "One Enter", Time.frameCount); 82 | oneEnter++; 83 | } 84 | 85 | void One_Foo() 86 | { 87 | //Debug.LogFormat("State:{0} Frame:{1}", "One Foo", Time.frameCount); 88 | oneFoo++; 89 | } 90 | 91 | void One_Bar(int value) 92 | { 93 | //Debug.LogFormat("State:{0} Frame:{1}", "One Bar", Time.frameCount); 94 | oneBar++; 95 | oneBarValue = value; 96 | } 97 | 98 | void One_Baz(int valueA, int valueB) 99 | { 100 | //Debug.LogFormat("State:{0} Frame:{1}", "One Baz", Time.frameCount); 101 | oneBaz++; 102 | oneBazValueA = valueA; 103 | oneBazValueB = valueB; 104 | } 105 | 106 | void One_Exit() 107 | { 108 | //Debug.LogFormat("State:{0} Frame:{1}", "One Exit", Time.frameCount); 109 | oneExit++; 110 | } 111 | 112 | void Two_Enter() 113 | { 114 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Enter", Time.frameCount); 115 | twoEnter++; 116 | } 117 | 118 | void Two_Foo() 119 | { 120 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Foo", Time.frameCount); 121 | twoFoo++; 122 | } 123 | 124 | void Two_Bar(int value) 125 | { 126 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Bar", Time.frameCount); 127 | twoBar++; 128 | twoBarValue = value; 129 | } 130 | 131 | void Two_Baz(int valueA, int valueB) 132 | { 133 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Baz", Time.frameCount); 134 | twoBaz++; 135 | twoBazValueA = valueA; 136 | twoBazValueB = valueB; 137 | } 138 | 139 | void Two_Exit() 140 | { 141 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Exit", Time.frameCount); 142 | twoExit++; 143 | } 144 | } 145 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestDriverLifecycle.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1ef0a3dffdbf4a6e8c8ff686a0b6efa3 3 | timeCreated: 1616931919 -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestEmptyDriver.cs: -------------------------------------------------------------------------------- 1 | using MonsterLove.StateMachine; 2 | using NUnit.Framework; 3 | using UnityEngine; 4 | 5 | public class TestEmptyDriver 6 | { 7 | public enum States 8 | { 9 | One, 10 | Two, 11 | Three, 12 | Four, 13 | } 14 | 15 | public class Driver 16 | { 17 | } 18 | 19 | private GameObject go; 20 | private StateClass behaviour; 21 | private StateMachine fsm; 22 | 23 | [SetUp] 24 | public void Init() 25 | { 26 | go = new GameObject(); 27 | behaviour = go.AddComponent(); 28 | 29 | fsm = new StateMachine(behaviour); 30 | } 31 | 32 | [TearDown] 33 | public void Kill() 34 | { 35 | Object.DestroyImmediate(go); 36 | } 37 | 38 | 39 | [Test] 40 | public void TestEmptyDriverUpdate() 41 | { 42 | fsm.ChangeState(States.One); 43 | 44 | Assert.AreEqual(1, behaviour.oneEnter); 45 | Assert.AreEqual(0, behaviour.oneExit); 46 | 47 | Assert.AreEqual(0, behaviour.twoEnter); 48 | Assert.AreEqual(0, behaviour.twoExit); 49 | 50 | fsm.ChangeState(States.Two); 51 | 52 | Assert.AreEqual(1, behaviour.oneEnter); 53 | Assert.AreEqual(1, behaviour.oneExit); 54 | 55 | Assert.AreEqual(1, behaviour.twoEnter); 56 | Assert.AreEqual(0, behaviour.twoExit); 57 | } 58 | 59 | private class StateClass : MonoBehaviour 60 | { 61 | public int oneEnter; 62 | public int oneFoo; 63 | public int oneBar; 64 | public int oneBaz; 65 | public int oneExit; 66 | 67 | public int oneBarValue; 68 | public int oneBazValueA; 69 | public int oneBazValueB; 70 | 71 | public int twoEnter; 72 | public int twoFoo; 73 | public int twoBar; 74 | public int twoBaz; 75 | public int twoExit; 76 | 77 | public int twoBarValue; 78 | public int twoBazValueA; 79 | public int twoBazValueB; 80 | 81 | void One_Enter() 82 | { 83 | //Debug.LogFormat("State:{0} Frame:{1}", "One Enter", Time.frameCount); 84 | oneEnter++; 85 | } 86 | 87 | void One_Foo() 88 | { 89 | //Debug.LogFormat("State:{0} Frame:{1}", "One Foo", Time.frameCount); 90 | oneFoo++; 91 | } 92 | 93 | void One_Bar(int value) 94 | { 95 | //Debug.LogFormat("State:{0} Frame:{1}", "One Bar", Time.frameCount); 96 | oneBar++; 97 | oneBarValue = value; 98 | } 99 | 100 | void One_Baz(int valueA, int valueB) 101 | { 102 | //Debug.LogFormat("State:{0} Frame:{1}", "One Baz", Time.frameCount); 103 | oneBaz++; 104 | oneBazValueA = valueA; 105 | oneBazValueB = valueB; 106 | } 107 | 108 | void One_Exit() 109 | { 110 | //Debug.LogFormat("State:{0} Frame:{1}", "One Exit", Time.frameCount); 111 | oneExit++; 112 | } 113 | 114 | void Two_Enter() 115 | { 116 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Enter", Time.frameCount); 117 | twoEnter++; 118 | } 119 | 120 | void Two_Foo() 121 | { 122 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Foo", Time.frameCount); 123 | twoFoo++; 124 | } 125 | 126 | void Two_Bar(int value) 127 | { 128 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Bar", Time.frameCount); 129 | twoBar++; 130 | twoBarValue = value; 131 | } 132 | 133 | void Two_Baz(int valueA, int valueB) 134 | { 135 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Baz", Time.frameCount); 136 | twoBaz++; 137 | twoBazValueA = valueA; 138 | twoBazValueB = valueB; 139 | } 140 | 141 | void Two_Exit() 142 | { 143 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Exit", Time.frameCount); 144 | twoExit++; 145 | } 146 | } 147 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestEmptyDriver.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d6391192757a422793fc48ab8a3fd5b7 3 | timeCreated: 1568191151 -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestInheritedDriver.cs: -------------------------------------------------------------------------------- 1 | using MonsterLove.StateMachine; 2 | using NUnit.Framework; 3 | using UnityEngine; 4 | 5 | public class TestInheritedDriver 6 | { 7 | public enum States 8 | { 9 | One, 10 | Two, 11 | Three, 12 | Four, 13 | } 14 | 15 | public class Driver : StateDriverUnity 16 | { 17 | public StateEvent Foo; 18 | } 19 | 20 | private GameObject go; 21 | private StateClass behaviour; 22 | private StateMachine fsm; 23 | 24 | [SetUp] 25 | public void Init() 26 | { 27 | go = new GameObject(); 28 | behaviour = go.AddComponent(); 29 | 30 | fsm = new StateMachine(behaviour); 31 | } 32 | 33 | [TearDown] 34 | public void Kill() 35 | { 36 | Object.DestroyImmediate(go); 37 | } 38 | 39 | [Test] 40 | public void TestDriverNotNull() 41 | { 42 | Assert.NotNull(fsm.Driver); 43 | } 44 | 45 | [Test] 46 | public void TestCustomEvents() 47 | { 48 | fsm.ChangeState(States.One); 49 | 50 | fsm.Driver.Foo.Invoke(); 51 | fsm.Driver.Update.Invoke(); 52 | 53 | Assert.AreEqual(1, behaviour.oneFoo); 54 | Assert.AreEqual(1, behaviour.oneUpdate); 55 | 56 | Assert.AreEqual(0, behaviour.twoFoo); 57 | Assert.AreEqual(0, behaviour.twoUpdate); 58 | 59 | fsm.ChangeState(States.Two); 60 | 61 | fsm.Driver.Foo.Invoke(); 62 | fsm.Driver.Update.Invoke(); 63 | 64 | Assert.AreEqual(1, behaviour.oneFoo); 65 | Assert.AreEqual(1, behaviour.oneUpdate); 66 | 67 | Assert.AreEqual(1, behaviour.twoFoo); 68 | Assert.AreEqual(1, behaviour.twoUpdate); 69 | } 70 | 71 | private class StateClass : MonoBehaviour 72 | { 73 | public int oneEnter; 74 | public int oneFoo; 75 | public int oneUpdate; 76 | public int oneExit; 77 | 78 | public int twoEnter; 79 | public int twoFoo; 80 | public int twoUpdate; 81 | public int twoExit; 82 | 83 | void One_Enter() 84 | { 85 | //Debug.LogFormat("State:{0} Frame:{1}", "One Enter", Time.frameCount); 86 | oneEnter++; 87 | } 88 | 89 | void One_Foo() 90 | { 91 | //Debug.LogFormat("State:{0} Frame:{1}", "One Foo", Time.frameCount); 92 | oneFoo++; 93 | } 94 | 95 | void One_Update() 96 | { 97 | oneUpdate++; 98 | } 99 | 100 | void One_Exit() 101 | { 102 | //Debug.LogFormat("State:{0} Frame:{1}", "One Exit", Time.frameCount); 103 | oneExit++; 104 | } 105 | 106 | void Two_Enter() 107 | { 108 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Enter", Time.frameCount); 109 | twoEnter++; 110 | } 111 | 112 | void Two_Foo() 113 | { 114 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Foo", Time.frameCount); 115 | twoFoo++; 116 | } 117 | 118 | void Two_Update() 119 | { 120 | twoUpdate++; 121 | } 122 | 123 | void Two_Exit() 124 | { 125 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Exit", Time.frameCount); 126 | twoExit++; 127 | } 128 | } 129 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestInheritedDriver.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7fe6b2aed376482ab4ab9842c0e791b3 3 | timeCreated: 1568136312 -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestMultipleSubscribers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MonsterLove.StateMachine; 3 | using NUnit.Framework; 4 | using UnityEngine; 5 | using UnityEditor; 6 | using System.Collections; 7 | using Object = UnityEngine.Object; 8 | 9 | [TestFixture] 10 | [Category("State Machine Tests")] 11 | internal class TestMultipleSubscribers 12 | { 13 | public enum States 14 | { 15 | One, 16 | Two, 17 | Three, 18 | } 19 | 20 | private GameObject go; 21 | private ClassWithBasicStates behaviour1; 22 | private ClassWithBasicStates behaviour2; 23 | private ClassWithBasicStates behaviour3; 24 | private StateMachineRunner engine; 25 | private StateMachine fsm; 26 | 27 | [SetUp] 28 | public void Init() 29 | { 30 | go = new GameObject("stateTest"); 31 | behaviour1 = go.AddComponent(); 32 | behaviour2 = go.AddComponent(); 33 | behaviour3 = go.AddComponent(); 34 | engine = go.AddComponent(); 35 | } 36 | 37 | [TearDown] 38 | public void Kill() 39 | { 40 | Object.DestroyImmediate(go); 41 | } 42 | 43 | [Test] 44 | public void TestNoCrossTalk() 45 | { 46 | var fsm1 = engine.Initialize(behaviour1, States.One); 47 | var fsm2 = engine.Initialize(behaviour2, States.Two); 48 | var fsm3 = engine.Initialize(behaviour3, States.One); 49 | 50 | fsm2.ChangeState(States.Three); 51 | fsm2.ChangeState(States.Two); 52 | 53 | fsm3.ChangeState(States.Three); 54 | 55 | 56 | Assert.AreEqual(1, behaviour1.oneStats.enterCount); 57 | Assert.AreEqual(0, behaviour1.oneStats.exitCount); 58 | Assert.AreEqual(0, behaviour1.twoStats.enterCount); 59 | Assert.AreEqual(0, behaviour1.twoStats.exitCount); 60 | Assert.AreEqual(0, behaviour1.threeStats.enterCount); 61 | Assert.AreEqual(0, behaviour1.threeStats.exitCount); 62 | 63 | Assert.AreEqual(0, behaviour2.oneStats.enterCount); 64 | Assert.AreEqual(0, behaviour2.oneStats.exitCount); 65 | Assert.AreEqual(2, behaviour2.twoStats.enterCount); 66 | Assert.AreEqual(1, behaviour2.twoStats.exitCount); 67 | Assert.AreEqual(1, behaviour2.threeStats.enterCount); 68 | Assert.AreEqual(1, behaviour2.threeStats.exitCount); 69 | 70 | Assert.AreEqual(1, behaviour3.oneStats.enterCount); 71 | Assert.AreEqual(1, behaviour3.oneStats.exitCount); 72 | Assert.AreEqual(0, behaviour3.twoStats.enterCount); 73 | Assert.AreEqual(0, behaviour3.twoStats.exitCount); 74 | Assert.AreEqual(1, behaviour3.threeStats.enterCount); 75 | Assert.AreEqual(0, behaviour3.threeStats.exitCount); 76 | } 77 | 78 | 79 | } 80 | 81 | 82 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestMultipleSubscribers.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 871e6dc4ae40b964f999b5a2b4b88147 3 | timeCreated: 1457534452 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestNonStandardEnums.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using MonsterLove.StateMachine; 4 | using NUnit.Framework; 5 | using UnityEditor; 6 | using UnityEngine; 7 | using UnityEngine.TestTools; 8 | using Object = UnityEngine.Object; 9 | 10 | public class TestNonStandardEnums 11 | { 12 | private enum StatesUlong : ulong 13 | { 14 | Foo = ulong.MaxValue, 15 | } 16 | 17 | private GameObject go; 18 | private StateClass behaviour; 19 | private StateMachine fsm; 20 | 21 | [SetUp] 22 | public void Init() 23 | { 24 | go = new GameObject(); 25 | behaviour = go.AddComponent(); 26 | } 27 | 28 | [TearDown] 29 | public void Kill() 30 | { 31 | Object.DestroyImmediate(go); 32 | } 33 | 34 | [Test] 35 | public void TestNonIntEnumErrors() 36 | { 37 | Assert.Catch(typeof(ArgumentException), () => 38 | { 39 | fsm = new StateMachine(behaviour); 40 | }); 41 | } 42 | 43 | private class StateClass : MonoBehaviour 44 | { 45 | 46 | } 47 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestNonStandardEnums.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 58f27538abe6462f9ed6996603c5017b 3 | timeCreated: 1616936058 -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestStateClassTypesMismatchDriver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MonsterLove.StateMachine; 3 | using NUnit.Framework; 4 | using UnityEngine; 5 | using Object = UnityEngine.Object; 6 | 7 | public class TestStateClassTypesMismatchDriver 8 | { 9 | public enum States 10 | { 11 | One, 12 | Two, 13 | Three, 14 | Four, 15 | } 16 | 17 | public class Driver 18 | { 19 | public StateEvent Foo; 20 | public StateEvent Bar; 21 | public StateEvent Baz; 22 | } 23 | 24 | private GameObject go; 25 | private StateClass behaviour; 26 | private StateMachine fsm; 27 | 28 | [SetUp] 29 | public void Init() 30 | { 31 | go = new GameObject(); 32 | behaviour = go.AddComponent(); 33 | } 34 | 35 | [TearDown] 36 | public void Kill() 37 | { 38 | Object.DestroyImmediate(go); 39 | } 40 | 41 | [Test] 42 | public void TestMismatchedEvents() 43 | { 44 | Assert.Throws(() => 45 | new StateMachine(behaviour) 46 | ); 47 | } 48 | 49 | private class StateClass : MonoBehaviour 50 | { 51 | public int oneEnter; 52 | public int oneFoo; 53 | public int oneBar; 54 | public int oneBaz; 55 | public int oneExit; 56 | 57 | public int oneBarValue; 58 | public int oneBazValueA; 59 | public int oneBazValueB; 60 | 61 | public int twoEnter; 62 | public int twoExit; 63 | 64 | void One_Enter() 65 | { 66 | //Debug.LogFormat("State:{0} Frame:{1}", "One Enter", Time.frameCount); 67 | oneEnter++; 68 | } 69 | 70 | void One_Baz() 71 | { 72 | //Debug.LogFormat("State:{0} Frame:{1}", "One Foo", Time.frameCount); 73 | oneFoo++; 74 | } 75 | 76 | void One_Foo(int value) 77 | { 78 | //Debug.LogFormat("State:{0} Frame:{1}", "One Bar", Time.frameCount); 79 | oneBar++; 80 | oneBarValue = value; 81 | } 82 | 83 | void One_Bar(int valueA, int valueB) 84 | { 85 | //Debug.LogFormat("State:{0} Frame:{1}", "One Baz", Time.frameCount); 86 | oneBaz++; 87 | oneBazValueA = valueA; 88 | oneBazValueB = valueB; 89 | } 90 | 91 | void One_Exit() 92 | { 93 | //Debug.LogFormat("State:{0} Frame:{1}", "One Exit", Time.frameCount); 94 | oneExit++; 95 | } 96 | 97 | void Two_Enter() 98 | { 99 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Enter", Time.frameCount); 100 | twoEnter++; 101 | } 102 | 103 | void Two_Exit() 104 | { 105 | //Debug.LogFormat("State:{0} Frame:{1}", "Two Exit", Time.frameCount); 106 | twoExit++; 107 | } 108 | } 109 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestStateClassTypesMismatchDriver.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ac06595e9bcd40348af830ec6a29a7a5 3 | timeCreated: 1568133089 -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestStateEngineInitialization.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MonsterLove.StateMachine; 3 | using NUnit.Framework; 4 | using UnityEngine; 5 | using Object = UnityEngine.Object; 6 | 7 | [TestFixture] 8 | [Category("State Machine Tests")] 9 | public class TestStateEngineInitialization 10 | { 11 | 12 | public enum TestStates 13 | { 14 | StateInit, 15 | StatePlay, 16 | StateEnd, 17 | } 18 | 19 | public enum TestNoDefines 20 | { 21 | } 22 | 23 | private GameObject go; 24 | private ClassWithBasicStates behaviour; 25 | private StateMachineRunner engine; 26 | 27 | [SetUp] 28 | public void Init() 29 | { 30 | go = new GameObject("stateTest"); 31 | behaviour = go.AddComponent(); 32 | engine = go.AddComponent(); 33 | } 34 | 35 | [TearDown] 36 | public void Kill() 37 | { 38 | Object.DestroyImmediate(go); 39 | } 40 | 41 | [Test] 42 | public void TestInitializedTwice() 43 | { 44 | //Should this throw an error? I'm not sure? 45 | var fsm = engine.Initialize(behaviour); 46 | fsm = engine.Initialize(behaviour); 47 | } 48 | 49 | [Test] 50 | public void TestStatesDefined() 51 | { 52 | Assert.Throws( 53 | () => { engine.Initialize(behaviour); } 54 | ); 55 | } 56 | 57 | [Test] 58 | public void TestStatePropBeforeChange() 59 | { 60 | var fsm = new StateMachine(behaviour); 61 | 62 | Assert.Throws(() => 63 | { 64 | TestStates state = fsm.State; 65 | }); 66 | 67 | fsm.ChangeState(TestStates.StateInit); 68 | 69 | Assert.AreEqual(TestStates.StateInit, fsm.State); 70 | } 71 | 72 | [Test] 73 | public void TestLastStatePropBeforeChange() 74 | { 75 | var fsm = new StateMachine(behaviour); 76 | 77 | Assert.Throws(() => 78 | { 79 | TestStates state = fsm.LastState; 80 | }); 81 | Assert.IsFalse(fsm.LastStateExists); 82 | 83 | 84 | fsm.ChangeState(TestStates.StateInit); 85 | 86 | //Conflicted about this. Prefer to return default values, or the current state 87 | //but that would undermine correctness 88 | Assert.Throws(() => 89 | { 90 | TestStates state = fsm.LastState; 91 | }); 92 | Assert.IsFalse(fsm.LastStateExists); 93 | 94 | fsm.ChangeState(TestStates.StatePlay); 95 | 96 | Assert.AreEqual(TestStates.StateInit, fsm.LastState); 97 | Assert.IsTrue(fsm.LastStateExists); 98 | } 99 | } 100 | 101 | 102 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Editor/TestStateEngineInitialization.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d88daf46dc6100c44a16b31a04a34481 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4f46855213027aa4c83ef9e551448ea5 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Runtime/ClassDerivedFromSuperClass.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using MonsterLove.StateMachine; 4 | 5 | public class ClassDerivedFromSuperClass : ClassWithBasicStates 6 | { 7 | } 8 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Runtime/ClassDerivedFromSuperClass.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 56b834ac2387fd9428fa8e3d03e15af9 3 | timeCreated: 1466594866 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Runtime/ClassWithBasicStates.cs: -------------------------------------------------------------------------------- 1 | using MonsterLove.StateMachine; 2 | using UnityEngine; 3 | using System.Collections; 4 | 5 | public class ClassWithBasicStates : MonoBehaviour 6 | { 7 | public ClassWithBasicStatesTestHelper oneStats = new ClassWithBasicStatesTestHelper(); 8 | public ClassWithBasicStatesTestHelper twoStats = new ClassWithBasicStatesTestHelper(); 9 | public ClassWithBasicStatesTestHelper threeStats = new ClassWithBasicStatesTestHelper(); 10 | 11 | protected void One_Enter() 12 | { 13 | oneStats.enterCount++; 14 | } 15 | 16 | protected void One_Update() 17 | { 18 | oneStats.updateCount++; 19 | } 20 | 21 | protected void One_LateUpdate() 22 | { 23 | oneStats.lateUpdateCount++; 24 | } 25 | 26 | protected void One_Exit() 27 | { 28 | oneStats.exitCount++; 29 | } 30 | 31 | protected void One_Finally() 32 | { 33 | oneStats.finallyCount++; 34 | } 35 | 36 | protected void Two_Enter() 37 | { 38 | twoStats.enterCount++; 39 | } 40 | 41 | protected void Two_Update() 42 | { 43 | twoStats.updateCount++; 44 | } 45 | 46 | protected void Two_LateUpdate() 47 | { 48 | twoStats.lateUpdateCount++; 49 | } 50 | 51 | protected void Two_Exit() 52 | { 53 | twoStats.exitCount++; 54 | } 55 | 56 | protected void Two_Finally() 57 | { 58 | twoStats.finallyCount++; 59 | } 60 | 61 | protected void Three_Enter() 62 | { 63 | threeStats.enterCount++; 64 | } 65 | 66 | protected void Three_Update() 67 | { 68 | threeStats.updateCount++; 69 | } 70 | 71 | protected void Three_LateUpdate() 72 | { 73 | threeStats.lateUpdateCount++; 74 | } 75 | 76 | protected void Three_Exit() 77 | { 78 | threeStats.exitCount++; 79 | } 80 | 81 | protected void Three_Finally() 82 | { 83 | threeStats.finallyCount++; 84 | } 85 | } 86 | 87 | [System.Serializable] 88 | public class ClassWithBasicStatesTestHelper 89 | { 90 | public int enterCount; 91 | public int updateCount; 92 | public int lateUpdateCount; 93 | public int exitCount; 94 | public int finallyCount; 95 | } 96 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Runtime/ClassWithBasicStates.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f41bf36ff667bf844808b5e9fa28af3f 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Runtime/MonsterLove.StateMachine.Tests.Runtime.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MonsterLove.StateMachine.Tests.Runtime", 3 | "references": [ 4 | "MonsterLove.StateMachine.Runtime", 5 | "UnityEngine.TestRunner", 6 | "UnityEditor.TestRunner" 7 | ], 8 | "includePlatforms": [], 9 | "excludePlatforms": [], 10 | "allowUnsafeCode": false, 11 | "overrideReferences": true, 12 | "precompiledReferences": [ 13 | "nunit.framework.dll" 14 | ], 15 | "autoReferenced": false, 16 | "defineConstraints": [ 17 | "UNITY_INCLUDE_TESTS" 18 | ], 19 | "versionDefines": [], 20 | "noEngineReferences": false 21 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Runtime/MonsterLove.StateMachine.Tests.Runtime.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f9fb370cdd6625f4fb8a0dec85124b0c 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Runtime/TestChangeAsyncCustomDriver.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using MonsterLove.StateMachine; 3 | using NUnit.Framework; 4 | using UnityEngine; 5 | using UnityEngine.TestTools; 6 | 7 | namespace Tests 8 | { 9 | public class TestAsyncCustomDriver 10 | { 11 | public enum States 12 | { 13 | One, 14 | Two, 15 | Three, 16 | Four, 17 | } 18 | 19 | private GameObject go; 20 | private StateClass behaviour; 21 | private StateMachine fsm; 22 | 23 | [SetUp] 24 | public void Init() 25 | { 26 | go = new GameObject(); 27 | behaviour = go.AddComponent(); 28 | 29 | fsm = new StateMachine(behaviour); 30 | behaviour.fsm = fsm; 31 | } 32 | 33 | [TearDown] 34 | public void Kill() 35 | { 36 | Object.Destroy(go); 37 | } 38 | 39 | [UnityTest] 40 | public IEnumerator TestChange() 41 | { 42 | // /1 43 | fsm.ChangeState(States.One); 44 | 45 | yield return null; 46 | 47 | Assert.AreEqual(0, behaviour.oneEnter); 48 | Assert.AreEqual(0, behaviour.oneUpdate); //Enter still running, no update called 49 | 50 | yield return null; 51 | 52 | Assert.AreEqual(1, behaviour.oneEnter); //Enter now complete 53 | Assert.AreEqual(0, behaviour.oneUpdate); //Update executes before co-routine, therefore update not run yet 54 | 55 | yield return null; 56 | 57 | Assert.AreEqual(1, behaviour.oneEnter); 58 | Assert.AreEqual(1, behaviour.oneUpdate); //Update has first chance to run 59 | } 60 | 61 | private class StateClass : MonoBehaviour 62 | { 63 | public StateMachine fsm; 64 | 65 | public int oneEnter; 66 | public int oneUpdate; 67 | public int oneExit; 68 | public int oneFinally; 69 | 70 | public int twoEnter; 71 | public int twoUpdate; 72 | public int twoExit; 73 | public int twoFinally; 74 | 75 | public int threeEnter; 76 | public int threeUpdate; 77 | public int threeExit; 78 | public int threeFinally; 79 | 80 | public int fourEnter; 81 | public int fourUpdate; 82 | public int fourExit; 83 | public int fourFinally; 84 | 85 | void Update() 86 | { 87 | fsm.Driver.Update.Invoke(); 88 | } 89 | 90 | IEnumerator One_Enter() 91 | { 92 | Debug.LogFormat("State:{0} Frame:{1}", "One Enter Start", Time.frameCount); 93 | 94 | yield return null; 95 | yield return null; 96 | 97 | Debug.LogFormat("State:{0} Frame:{1}", "One Enter End", Time.frameCount); 98 | 99 | oneEnter++; 100 | } 101 | 102 | void One_Update() 103 | { 104 | Debug.LogFormat("State:{0} Frame:{1}", "One Update", Time.frameCount); 105 | oneUpdate++; 106 | } 107 | 108 | IEnumerator One_Exit() 109 | { 110 | Debug.LogFormat("State:{0} Frame:{1}", "One Exit Start", Time.frameCount); 111 | 112 | yield return null; 113 | yield return null; 114 | 115 | Debug.LogFormat("State:{0} Frame:{1}", "One Exit End", Time.frameCount); 116 | 117 | oneExit++; 118 | } 119 | 120 | void One_Finally() 121 | { 122 | Debug.LogFormat("State:{0} Frame:{1}", "One Finally", Time.frameCount); 123 | oneFinally++; 124 | } 125 | 126 | void Two_Enter() 127 | { 128 | Debug.LogFormat("State:{0} Frame:{1}", "Two Enter", Time.frameCount); 129 | twoEnter++; 130 | } 131 | 132 | void Two_Update() 133 | { 134 | Debug.LogFormat("State:{0} Frame:{1}", "Two Update", Time.frameCount); 135 | twoUpdate++; 136 | } 137 | 138 | void Two_Exit() 139 | { 140 | Debug.LogFormat("State:{0} Frame:{1}", "Two Exit", Time.frameCount); 141 | twoExit++; 142 | } 143 | 144 | void Two_Finally() 145 | { 146 | Debug.LogFormat("State:{0} Frame:{1}", "Two Finally", Time.frameCount); 147 | twoFinally++; 148 | } 149 | 150 | void Three_Enter() 151 | { 152 | Debug.LogFormat("State:{0} Frame:{1}", "Three Enter", Time.frameCount); 153 | threeEnter++; 154 | } 155 | 156 | void Three_Update() 157 | { 158 | Debug.LogFormat("State:{0} Frame:{1}", "Three Update", Time.frameCount); 159 | threeUpdate++; 160 | } 161 | 162 | void Three_Exit() 163 | { 164 | Debug.LogFormat("State:{0} Frame:{1}", "Three Exit", Time.frameCount); 165 | threeExit++; 166 | } 167 | 168 | void Three_Finally() 169 | { 170 | Debug.LogFormat("State:{0} Frame:{1}", "Three Finally", Time.frameCount); 171 | threeFinally++; 172 | } 173 | 174 | void Four_Enter() 175 | { 176 | Debug.LogFormat("State:{0} Frame:{1}", "Four Enter", Time.frameCount); 177 | fourEnter++; 178 | } 179 | 180 | void Four_Update() 181 | { 182 | Debug.LogFormat("State:{0} Frame:{1}", "Four Update", Time.frameCount); 183 | fourUpdate++; 184 | } 185 | 186 | void Four_Exit() 187 | { 188 | Debug.LogFormat("State:{0} Frame:{1}", "Four Exit", Time.frameCount); 189 | fourExit++; 190 | } 191 | 192 | void Four_Finally() 193 | { 194 | Debug.LogFormat("State:{0} Frame:{1}", "Four Finally", Time.frameCount); 195 | fourFinally++; 196 | } 197 | } 198 | } 199 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Runtime/TestChangeAsyncCustomDriver.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7b734601d42952c488c972b05398a234 3 | timeCreated: 1567675903 -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Runtime/TestChangeAsyncOverwrite.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using MonsterLove.StateMachine; 3 | using NUnit.Framework; 4 | using UnityEngine; 5 | using UnityEngine.TestTools; 6 | 7 | namespace Tests 8 | { 9 | public class TestChangeAsyncOverwrite 10 | { 11 | public enum States 12 | { 13 | One, 14 | Two, 15 | Three, 16 | Four, 17 | } 18 | 19 | private GameObject go; 20 | private StateClass behaviour; 21 | private StateMachine fsm; 22 | private float duration = 0.5f; 23 | 24 | [SetUp] 25 | public void Init() 26 | { 27 | go = new GameObject(); 28 | behaviour = go.AddComponent(); 29 | behaviour.duration = duration; 30 | 31 | fsm = StateMachine.Initialize(behaviour); 32 | } 33 | 34 | [TearDown] 35 | public void Kill() 36 | { 37 | Object.Destroy(go); 38 | } 39 | 40 | [UnityTest] 41 | public IEnumerator TestAsyncEnterExit() 42 | { 43 | // 1 44 | fsm.ChangeState(States.One, StateTransition.Overwrite); 45 | 46 | // 1*__/2 47 | fsm.ChangeState(States.Two, StateTransition.Overwrite); 48 | 49 | Assert.AreEqual(States.One, fsm.LastState); 50 | Assert.AreEqual(States.Two, fsm.State); 51 | Assert.AreEqual(States.Two, fsm.NextState); 52 | 53 | yield return new WaitForSeconds(duration + 0.2f); 54 | 55 | Assert.AreEqual(1, behaviour.oneEnter); 56 | Assert.AreEqual(0, behaviour.oneUpdate); 57 | Assert.AreEqual(0, behaviour.oneExit); 58 | Assert.AreEqual(1, behaviour.oneFinally); 59 | 60 | Assert.AreEqual(1, behaviour.twoEnter); 61 | 62 | Assert.AreEqual(States.One, fsm.LastState); 63 | Assert.AreEqual(States.Two, fsm.State); 64 | Assert.AreEqual(States.Two, fsm.NextState); 65 | } 66 | 67 | [UnityTest] 68 | public IEnumerator TestChangeDuringAsyncEnter() 69 | { 70 | // 1 71 | fsm.ChangeState(States.One, StateTransition.Overwrite); 72 | 73 | // 1\__/2 74 | fsm.ChangeState(States.Two, StateTransition.Safe); 75 | 76 | Assert.AreEqual(false, fsm.LastStateExists); 77 | Assert.AreEqual(States.One, fsm.State); 78 | Assert.AreEqual(States.Two, fsm.NextState); 79 | 80 | yield return new WaitForSeconds(duration + duration * 0.5f); 81 | 82 | Assert.AreEqual(1, behaviour.oneEnter); 83 | Assert.AreEqual(0, behaviour.oneUpdate); 84 | Assert.AreEqual(1, behaviour.oneExit); 85 | Assert.AreEqual(1, behaviour.oneFinally); 86 | 87 | Assert.AreEqual(0, behaviour.twoEnter); 88 | 89 | Assert.AreEqual(0, behaviour.threeEnter); 90 | 91 | Assert.AreEqual(States.One, fsm.LastState); 92 | Assert.AreEqual(States.Two, fsm.State); 93 | Assert.AreEqual(States.Two, fsm.NextState); 94 | 95 | // 1\__*2__3 96 | fsm.ChangeState(States.Three, StateTransition.Overwrite); 97 | 98 | Assert.AreEqual(0, behaviour.twoEnter); //Intro never completes 99 | Assert.AreEqual(1, behaviour.twoExit); //Single frame Exit still fires. Arguably more consistent that exit doesn't fire, instead relying on finally(), however this would be a breaking change 100 | Assert.AreEqual(0, behaviour.twoUpdate); 101 | Assert.AreEqual(1, behaviour.twoFinally); 102 | 103 | Assert.AreEqual(1, behaviour.threeEnter); 104 | 105 | Assert.AreEqual(States.Two, fsm.LastState); 106 | Assert.AreEqual(States.Three, fsm.State); 107 | Assert.AreEqual(States.Three, fsm.NextState); 108 | } 109 | 110 | [UnityTest] 111 | public IEnumerator TestChangeDuringAsyncExit() 112 | { 113 | // 1 114 | fsm.ChangeState(States.One, StateTransition.Overwrite); 115 | 116 | // 1\__/2 117 | fsm.ChangeState(States.Two, StateTransition.Safe); 118 | 119 | Assert.AreEqual(false, fsm.LastStateExists); 120 | Assert.AreEqual(States.One, fsm.State); 121 | Assert.AreEqual(States.Two, fsm.NextState); 122 | 123 | yield return new WaitForSeconds(duration * 0.5f); 124 | 125 | Assert.AreEqual(1, behaviour.oneEnter); 126 | Assert.AreEqual(0, behaviour.oneUpdate); 127 | Assert.AreEqual(0, behaviour.oneExit); 128 | Assert.AreEqual(0, behaviour.oneFinally); 129 | 130 | Assert.AreEqual(0, behaviour.twoEnter); 131 | 132 | Assert.AreEqual(false, fsm.LastStateExists); 133 | Assert.AreEqual(States.One, fsm.State); 134 | Assert.AreEqual(States.Two, fsm.NextState); 135 | 136 | // 1*__/4 137 | fsm.ChangeState(States.Four, StateTransition.Overwrite); 138 | 139 | Assert.AreEqual(States.One, fsm.LastState); 140 | Assert.AreEqual(States.Four, fsm.State); 141 | Assert.AreEqual(States.Four, fsm.NextState); 142 | 143 | yield return new WaitForSeconds(duration + 0.2f); 144 | 145 | Assert.AreEqual(1, behaviour.oneEnter); 146 | Assert.AreEqual(0, behaviour.oneUpdate); 147 | Assert.AreEqual(0, behaviour.oneExit); //Cancelled - never completed 148 | Assert.AreEqual(1, behaviour.oneFinally); 149 | 150 | Assert.AreEqual(0, behaviour.twoEnter); //Never entered 151 | 152 | Assert.AreEqual(1, behaviour.fourEnter); 153 | 154 | Assert.AreEqual(States.One, fsm.LastState); 155 | Assert.AreEqual(States.Four, fsm.State); 156 | Assert.AreEqual(States.Four, fsm.NextState); 157 | } 158 | 159 | private class StateClass : MonoBehaviour 160 | { 161 | public float duration; 162 | 163 | public int oneEnter; 164 | public int oneUpdate; 165 | public int oneExit; 166 | public int oneFinally; 167 | 168 | public int twoEnter; 169 | public int twoUpdate; 170 | public int twoExit; 171 | public int twoFinally; 172 | 173 | public int threeEnter; 174 | public int threeUpdate; 175 | public int threeExit; 176 | public int threeFinally; 177 | 178 | public int fourEnter; 179 | public int fourUpdate; 180 | public int fourExit; 181 | public int fourFinally; 182 | 183 | void One_Enter() 184 | { 185 | Debug.LogFormat("State:{0} Frame:{1}", "One Enter", Time.frameCount); 186 | oneEnter++; 187 | } 188 | 189 | void One_Update() 190 | { 191 | Debug.LogFormat("State:{0} Frame:{1}", "One Update", Time.frameCount); 192 | oneUpdate++; 193 | } 194 | 195 | IEnumerator One_Exit() 196 | { 197 | Debug.LogFormat("State:{0} Frame:{1}", "One Exit Start", Time.frameCount); 198 | yield return new WaitForSeconds(duration); 199 | Debug.LogFormat("State:{0} Frame:{1}", "One Exit End", Time.frameCount); 200 | oneExit++; 201 | } 202 | 203 | void One_Finally() 204 | { 205 | Debug.LogFormat("State:{0} Frame:{1}", "One Finally", Time.frameCount); 206 | oneFinally++; 207 | } 208 | 209 | IEnumerator Two_Enter() 210 | { 211 | Debug.LogFormat("State:{0} Frame:{1}", "Two Enter Start", Time.frameCount); 212 | yield return new WaitForSeconds(duration); 213 | Debug.LogFormat("State:{0} Frame:{1}", "Two Enter End", Time.frameCount); 214 | twoEnter++; 215 | } 216 | 217 | void Two_Update() 218 | { 219 | Debug.LogFormat("State:{0} Frame:{1}", "Two Update", Time.frameCount); 220 | twoUpdate++; 221 | } 222 | 223 | void Two_Exit() 224 | { 225 | Debug.LogFormat("State:{0} Frame:{1}", "Two Exit", Time.frameCount); 226 | twoExit++; 227 | } 228 | 229 | void Two_Finally() 230 | { 231 | Debug.LogFormat("State:{0} Frame:{1}", "Two Finally", Time.frameCount); 232 | twoFinally++; 233 | } 234 | 235 | void Three_Enter() 236 | { 237 | Debug.LogFormat("State:{0} Frame:{1}", "Three Enter", Time.frameCount); 238 | threeEnter++; 239 | } 240 | 241 | void Three_Update() 242 | { 243 | Debug.LogFormat("State:{0} Frame:{1}", "Three Update", Time.frameCount); 244 | threeUpdate++; 245 | } 246 | 247 | void Three_Exit() 248 | { 249 | Debug.LogFormat("State:{0} Frame:{1}", "Three Exit", Time.frameCount); 250 | threeExit++; 251 | } 252 | 253 | void Three_Finally() 254 | { 255 | Debug.LogFormat("State:{0} Frame:{1}", "Three Finally", Time.frameCount); 256 | threeFinally++; 257 | } 258 | 259 | IEnumerator Four_Enter() 260 | { 261 | Debug.LogFormat("State:{0} Frame:{1}", "Four Enter Start", Time.frameCount); 262 | yield return new WaitForSeconds(duration); 263 | Debug.LogFormat("State:{0} Frame:{1}", "Four Enter End", Time.frameCount); 264 | fourEnter++; 265 | } 266 | 267 | void Four_Update() 268 | { 269 | Debug.LogFormat("State:{0} Frame:{1}", "Four Update", Time.frameCount); 270 | fourUpdate++; 271 | } 272 | 273 | void Four_Exit() 274 | { 275 | Debug.LogFormat("State:{0} Frame:{1}", "Four Exit", Time.frameCount); 276 | fourExit++; 277 | } 278 | 279 | void Four_Finally() 280 | { 281 | Debug.LogFormat("State:{0} Frame:{1}", "Four Finally", Time.frameCount); 282 | fourFinally++; 283 | } 284 | } 285 | } 286 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Runtime/TestChangeAsyncOverwrite.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1a082dc9366ca784087bde0dde49a5ce 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Runtime/TestChangeAsyncSafe.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using MonsterLove.StateMachine; 3 | using NUnit.Framework; 4 | using UnityEngine; 5 | using UnityEngine.TestTools; 6 | 7 | namespace Tests 8 | { 9 | public class TestChangeAsyncSafe 10 | { 11 | public enum States 12 | { 13 | One, 14 | Two, 15 | Three, 16 | Four, 17 | } 18 | 19 | private GameObject go; 20 | private StateClass behaviour; 21 | private StateMachine fsm; 22 | private float duration = 0.5f; 23 | 24 | [SetUp] 25 | public void Init() 26 | { 27 | go = new GameObject(); 28 | behaviour = go.AddComponent(); 29 | behaviour.duration = duration; 30 | 31 | fsm = StateMachine.Initialize(behaviour); 32 | } 33 | 34 | [TearDown] 35 | public void Kill() 36 | { 37 | Object.Destroy(go); 38 | } 39 | 40 | [UnityTest] 41 | public IEnumerator TestAsyncEnterExit() 42 | { 43 | // 1 44 | 45 | fsm.ChangeState(States.One, StateTransition.Safe); 46 | 47 | Assert.AreEqual(1, behaviour.oneEnter); 48 | Assert.AreEqual(0, behaviour.oneExit); 49 | Assert.AreEqual(0, behaviour.twoEnter); 50 | 51 | // 1\__/2 52 | 53 | fsm.ChangeState(States.Two, StateTransition.Safe); 54 | 55 | Assert.Catch(() => { var state = fsm.LastState;}); 56 | Assert.AreEqual(States.One, fsm.State); 57 | Assert.AreEqual(States.Two, fsm.NextState); 58 | 59 | Assert.AreEqual(1, behaviour.oneEnter); 60 | Assert.AreEqual(0, behaviour.oneExit); 61 | Assert.AreEqual(0, behaviour.twoEnter); 62 | 63 | yield return new WaitForSeconds(duration + duration + 0.2f); 64 | 65 | Assert.AreEqual(States.One, fsm.LastState); 66 | Assert.AreEqual(States.Two, fsm.State); 67 | Assert.AreEqual(States.Two, fsm.NextState); 68 | 69 | Assert.AreEqual(1, behaviour.oneEnter); 70 | Assert.AreEqual(1, behaviour.oneExit); 71 | Assert.AreEqual(1, behaviour.twoEnter); 72 | } 73 | 74 | [UnityTest] 75 | public IEnumerator TestChangeDuringAsyncEnter() 76 | { 77 | // 3 78 | fsm.ChangeState(States.Three, StateTransition.Safe); 79 | 80 | // 3__/2 81 | fsm.ChangeState(States.Two); 82 | 83 | Assert.AreEqual(1, behaviour.threeExit); 84 | 85 | Assert.AreEqual(0, behaviour.twoEnter); 86 | 87 | Assert.AreEqual(States.Three, fsm.LastState); 88 | Assert.AreEqual(States.Two, fsm.State); 89 | Assert.AreEqual(States.Two, fsm.NextState); 90 | 91 | yield return new WaitForSeconds(duration / 2f); 92 | 93 | // 3__/2\__4 //In safe mode, once a state is entered, both enter and exit are allowed to finish 94 | fsm.ChangeState(States.Four); 95 | 96 | Assert.AreEqual(1, behaviour.threeExit); 97 | 98 | Assert.AreEqual(0, behaviour.twoEnter); 99 | Assert.AreEqual(0, behaviour.twoUpdate); 100 | Assert.AreEqual(0, behaviour.twoExit); 101 | Assert.AreEqual(0, behaviour.twoFinally); 102 | 103 | Assert.AreEqual(0, behaviour.fourEnter); 104 | 105 | Assert.AreEqual(States.Three, fsm.LastState); 106 | Assert.AreEqual(States.Two, fsm.State); 107 | Assert.AreEqual(States.Four, fsm.NextState); 108 | 109 | yield return new WaitForSeconds(duration / 2f + duration + 0.2f); 110 | 111 | Assert.AreEqual(1, behaviour.threeExit); 112 | 113 | Assert.AreEqual(1, behaviour.twoEnter); 114 | Assert.AreEqual(1, behaviour.twoUpdate); //Single frame update while changing from Enter To Exit Routines. Not sure this is desired behaviour (zero update frames is more consistent), but don't want to cause a breaking change 115 | Assert.AreEqual(1, behaviour.twoExit); 116 | Assert.AreEqual(1, behaviour.twoFinally); 117 | 118 | Assert.AreEqual(1, behaviour.fourEnter); 119 | 120 | Assert.AreEqual(States.Two, fsm.LastState); 121 | Assert.AreEqual(States.Four, fsm.State); 122 | Assert.AreEqual(States.Four, fsm.NextState); 123 | } 124 | 125 | [UnityTest] 126 | public IEnumerator TestChangeDuringAsyncExit() 127 | { 128 | // 1 129 | fsm.ChangeState(States.One, StateTransition.Safe); 130 | 131 | // 1\__3 132 | fsm.ChangeState(States.Three, StateTransition.Safe); 133 | 134 | yield return new WaitForSeconds(duration / 2f); 135 | 136 | Assert.AreEqual(0, behaviour.oneExit); 137 | 138 | Assert.AreEqual(0, behaviour.threeEnter); 139 | Assert.AreEqual(0, behaviour.threeExit); 140 | 141 | Assert.AreEqual(0, behaviour.fourEnter); 142 | 143 | Assert.Catch(() => { var state = fsm.LastState;}); 144 | Assert.AreEqual(States.One, fsm.State); 145 | Assert.AreEqual(States.Three, fsm.NextState); 146 | 147 | // 1\__4 //In safe mode, before state is entered, newer state will supersede queued state 148 | fsm.ChangeState(States.Four); 149 | 150 | Assert.AreEqual(0, behaviour.oneExit); 151 | 152 | Assert.AreEqual(0, behaviour.threeEnter); 153 | Assert.AreEqual(0, behaviour.threeExit); 154 | 155 | Assert.AreEqual(0, behaviour.fourEnter); 156 | 157 | Assert.Catch(() => { var state = fsm.LastState;}); 158 | Assert.AreEqual(States.One, fsm.State); 159 | Assert.AreEqual(States.Four, fsm.NextState); 160 | 161 | yield return new WaitForSeconds(duration / 2f + 0.2f); 162 | 163 | Assert.AreEqual(1, behaviour.oneExit); 164 | 165 | Assert.AreEqual(0, behaviour.threeEnter); //Three never runs 166 | Assert.AreEqual(0, behaviour.threeExit); 167 | 168 | Assert.AreEqual(1, behaviour.fourEnter); 169 | 170 | Assert.AreEqual(States.One, fsm.LastState); 171 | Assert.AreEqual(States.Four, fsm.State); 172 | Assert.AreEqual(States.Four, fsm.NextState); 173 | } 174 | 175 | private class StateClass : MonoBehaviour 176 | { 177 | public float duration; 178 | 179 | public int oneEnter; 180 | public int oneUpdate; 181 | public int oneExit; 182 | public int oneFinally; 183 | 184 | public int twoEnter; 185 | public int twoUpdate; 186 | public int twoExit; 187 | public int twoFinally; 188 | 189 | public int threeEnter; 190 | public int threeUpdate; 191 | public int threeExit; 192 | public int threeFinally; 193 | 194 | public int fourEnter; 195 | public int fourUpdate; 196 | public int fourExit; 197 | public int fourFinally; 198 | 199 | void One_Enter() 200 | { 201 | Debug.LogFormat("State:{0} Frame:{1}", "One Enter", Time.frameCount); 202 | oneEnter++; 203 | } 204 | 205 | void One_Update() 206 | { 207 | Debug.LogFormat("State:{0} Frame:{1}", "One Update", Time.frameCount); 208 | oneUpdate++; 209 | } 210 | 211 | IEnumerator One_Exit() 212 | { 213 | Debug.LogFormat("State:{0} Frame:{1}", "One Exit Start", Time.frameCount); 214 | yield return new WaitForSeconds(duration); 215 | Debug.LogFormat("State:{0} Frame:{1}", "One Exit End", Time.frameCount); 216 | oneExit++; 217 | } 218 | 219 | void One_Finally() 220 | { 221 | Debug.LogFormat("State:{0} Frame:{1}", "One Finally", Time.frameCount); 222 | oneFinally++; 223 | } 224 | 225 | IEnumerator Two_Enter() 226 | { 227 | Debug.LogFormat("State:{0} Frame:{1}", "Two Enter Start", Time.frameCount); 228 | yield return new WaitForSeconds(duration); 229 | Debug.LogFormat("State:{0} Frame:{1}", "Two Enter End", Time.frameCount); 230 | twoEnter++; 231 | } 232 | 233 | void Two_Update() 234 | { 235 | Debug.LogFormat("State:{0} Frame:{1}", "Two Update", Time.frameCount); 236 | twoUpdate++; 237 | } 238 | 239 | IEnumerator Two_Exit() 240 | { 241 | Debug.LogFormat("State:{0} Frame:{1}", "Two Exit Start", Time.frameCount); 242 | twoExit++; 243 | yield return new WaitForSeconds(duration); 244 | Debug.LogFormat("State:{0} Frame:{1}", "Two Exit End", Time.frameCount); 245 | } 246 | 247 | void Two_Finally() 248 | { 249 | Debug.LogFormat("State:{0} Frame:{1}", "Two Finally", Time.frameCount); 250 | twoFinally++; 251 | } 252 | 253 | void Three_Enter() 254 | { 255 | Debug.LogFormat("State:{0} Frame:{1}", "Three Enter", Time.frameCount); 256 | threeEnter++; 257 | } 258 | 259 | void Three_Update() 260 | { 261 | Debug.LogFormat("State:{0} Frame:{1}", "Three Update", Time.frameCount); 262 | threeUpdate++; 263 | } 264 | 265 | void Three_Exit() 266 | { 267 | Debug.LogFormat("State:{0} Frame:{1}", "Three Exit", Time.frameCount); 268 | threeExit++; 269 | } 270 | 271 | void Three_Finally() 272 | { 273 | Debug.LogFormat("State:{0} Frame:{1}", "Three Finally", Time.frameCount); 274 | threeFinally++; 275 | } 276 | 277 | void Four_Enter() 278 | { 279 | Debug.LogFormat("State:{0} Frame:{1}", "Four Enter", Time.frameCount); 280 | fourEnter++; 281 | } 282 | 283 | void Four_Update() 284 | { 285 | Debug.LogFormat("State:{0} Frame:{1}", "Four Update", Time.frameCount); 286 | fourUpdate++; 287 | } 288 | 289 | void Four_Exit() 290 | { 291 | Debug.LogFormat("State:{0} Frame:{1}", "Four Exit", Time.frameCount); 292 | fourExit++; 293 | } 294 | 295 | void Four_Finally() 296 | { 297 | Debug.LogFormat("State:{0} Frame:{1}", "Four Finally", Time.frameCount); 298 | fourFinally++; 299 | } 300 | } 301 | } 302 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Runtime/TestChangeAsyncSafe.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6ba617b22bb510241b31b54b32315873 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Runtime/TestChangeFromTransition.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using MonsterLove.StateMachine; 4 | using NUnit.Framework; 5 | using UnityEngine; 6 | using UnityEngine.Analytics; 7 | using UnityEngine.TestTools; 8 | using Object = UnityEngine.Object; 9 | 10 | namespace Tests 11 | { 12 | // TEST DESCRIPTION 13 | // 14 | // Coverage for the scenario where state transition is aborted based on a flag evaluated within transition Enter and Exit methods 15 | public class TestChangeFromTransition 16 | { 17 | public enum States 18 | { 19 | One, 20 | Two, 21 | Three, 22 | Four, 23 | } 24 | 25 | private GameObject go; 26 | private StateClass behaviour; 27 | private StateMachine fsm; 28 | 29 | [SetUp] 30 | public void Init() 31 | { 32 | go = new GameObject(); 33 | behaviour = go.AddComponent(); 34 | 35 | fsm = StateMachine.Initialize(behaviour); 36 | behaviour.fsm = fsm; 37 | } 38 | 39 | [TearDown] 40 | public void Kill() 41 | { 42 | Object.Destroy(go); 43 | } 44 | 45 | [Test] 46 | public void TestChangeFromExit() 47 | { 48 | //TODO stack overflow is not the expected behaviour - also seems to be periodically crashing test suite. Disable for now 49 | 50 | // // 1 51 | // fsm.ChangeState(States.One); 52 | // 53 | // 54 | // 55 | // // 1-__3 //One_Exit contains change to 3 56 | // Assert.Throws( 57 | // ()=> fsm.ChangeState(States.Two) 58 | // ); 59 | // 60 | // 61 | // 62 | // // Assert.AreEqual(1, behaviour.oneEnter); 63 | // // Assert.AreEqual(0, behaviour.oneUpdate); 64 | // // Assert.AreEqual(1, behaviour.oneExit); 65 | // // Assert.AreEqual(1, behaviour.oneFinally); 66 | // // 67 | // // Assert.AreEqual(0, behaviour.twoEnter); 68 | // // Assert.AreEqual(0, behaviour.twoUpdate); 69 | // // Assert.AreEqual(0, behaviour.twoFinally); 70 | // // 71 | // // Assert.AreEqual(1, behaviour.threeEnter); 72 | } 73 | 74 | 75 | [Test] 76 | public void TestChangeFromEnter() 77 | { 78 | fsm.ChangeState(States.Two); 79 | 80 | // -4__3 //Four_Enter contains change to 3 81 | fsm.ChangeState(States.Four); 82 | 83 | Assert.AreEqual(1, behaviour.fourEnter); //This will complete after Exit and Finally. Not sure how to make this subtle side effect more obvious 84 | Assert.AreEqual(0, behaviour.fourUpdate); 85 | Assert.AreEqual(1, behaviour.fourExit); 86 | Assert.AreEqual(1, behaviour.fourFinally); 87 | 88 | Assert.AreEqual(1, behaviour.threeEnter); 89 | 90 | Assert.AreEqual(States.Four, fsm.LastState); 91 | Assert.AreEqual(States.Three, fsm.State); 92 | Assert.AreEqual(States.Three, fsm.NextState); 93 | } 94 | 95 | private class StateClass : MonoBehaviour 96 | { 97 | public StateMachine fsm; 98 | 99 | public int oneEnter; 100 | public int oneUpdate; 101 | public int oneExit; 102 | public int oneFinally; 103 | 104 | public int twoEnter; 105 | public int twoUpdate; 106 | public int twoExit; 107 | public int twoFinally; 108 | 109 | public int threeEnter; 110 | public int threeUpdate; 111 | public int threeExit; 112 | public int threeFinally; 113 | 114 | public int fourEnter; 115 | public int fourUpdate; 116 | public int fourExit; 117 | public int fourFinally; 118 | 119 | 120 | void One_Enter() 121 | { 122 | Debug.LogFormat("State:{0} Frame:{1}", "One Enter", Time.frameCount); 123 | oneEnter++; 124 | } 125 | 126 | void One_Update() 127 | { 128 | Debug.LogFormat("State:{0} Frame:{1}", "One Update", Time.frameCount); 129 | oneUpdate++; 130 | } 131 | 132 | void One_Exit() 133 | { 134 | fsm.ChangeState(States.Three); 135 | 136 | Debug.LogFormat("State:{0} Frame:{1}", "One Exit", Time.frameCount); 137 | oneExit++; 138 | } 139 | 140 | void One_Finally() 141 | { 142 | Debug.LogFormat("State:{0} Frame:{1}", "One Finally", Time.frameCount); 143 | oneFinally++; 144 | } 145 | 146 | void Two_Enter() 147 | { 148 | Debug.LogFormat("State:{0} Frame:{1}", "Two Enter", Time.frameCount); 149 | twoEnter++; 150 | } 151 | 152 | void Two_Update() 153 | { 154 | Debug.LogFormat("State:{0} Frame:{1}", "Two Update", Time.frameCount); 155 | twoUpdate++; 156 | } 157 | 158 | void Two_Exit() 159 | { 160 | Debug.LogFormat("State:{0} Frame:{1}", "Two Exit", Time.frameCount); 161 | twoExit++; 162 | } 163 | 164 | void Two_Finally() 165 | { 166 | Debug.LogFormat("State:{0} Frame:{1}", "Two Finally", Time.frameCount); 167 | twoFinally++; 168 | } 169 | 170 | void Three_Enter() 171 | { 172 | Debug.LogFormat("State:{0} Frame:{1}", "Three Enter", Time.frameCount); 173 | threeEnter++; 174 | } 175 | 176 | void Three_Update() 177 | { 178 | Debug.LogFormat("State:{0} Frame:{1}", "Three Update", Time.frameCount); 179 | threeUpdate++; 180 | } 181 | 182 | void Three_Exit() 183 | { 184 | Debug.LogFormat("State:{0} Frame:{1}", "Three Exit", Time.frameCount); 185 | threeExit++; 186 | } 187 | 188 | void Three_Finally() 189 | { 190 | Debug.LogFormat("State:{0} Frame:{1}", "Three Finally", Time.frameCount); 191 | threeFinally++; 192 | } 193 | 194 | void Four_Enter() 195 | { 196 | fsm.ChangeState(States.Three); 197 | Debug.LogFormat("State:{0} Frame:{1}", "Four Enter", Time.frameCount); 198 | fourEnter++; 199 | } 200 | 201 | void Four_Update() 202 | { 203 | Debug.LogFormat("State:{0} Frame:{1}", "Four Update", Time.frameCount); 204 | fourUpdate++; 205 | } 206 | 207 | void Four_Exit() 208 | { 209 | Debug.LogFormat("State:{0} Frame:{1}", "Four Exit", Time.frameCount); 210 | fourExit++; 211 | } 212 | 213 | void Four_Finally() 214 | { 215 | Debug.LogFormat("State:{0} Frame:{1}", "Four Finally", Time.frameCount); 216 | fourFinally++; 217 | } 218 | } 219 | } 220 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Runtime/TestChangeFromTransition.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: edc9ab4afa17406b8cdfe574960c6177 3 | timeCreated: 1567694365 -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Runtime/TestChangeState.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using MonsterLove.StateMachine; 3 | using NUnit.Framework; 4 | using UnityEngine; 5 | using UnityEngine.TestTools; 6 | 7 | namespace Tests 8 | { 9 | public class TestChangeState 10 | { 11 | public enum States 12 | { 13 | One, 14 | Two, 15 | Three, 16 | Four, 17 | } 18 | 19 | private GameObject go; 20 | private StateClass behaviour; 21 | private StateMachine fsm; 22 | 23 | [SetUp] 24 | public void Init() 25 | { 26 | go = new GameObject(); 27 | behaviour = go.AddComponent(); 28 | 29 | fsm = StateMachine.Initialize(behaviour); 30 | } 31 | 32 | [TearDown] 33 | public void Kill() 34 | { 35 | Object.Destroy(go); 36 | } 37 | 38 | [UnityTest] 39 | public IEnumerator TestChange() 40 | { 41 | fsm.ChangeState(States.One); 42 | 43 | Assert.Catch(()=> 44 | { 45 | var last = fsm.LastState; 46 | }); 47 | Assert.AreEqual(States.One, fsm.State); 48 | Assert.AreEqual(States.One, fsm.NextState); 49 | 50 | yield return null; 51 | 52 | fsm.ChangeState(States.Two); 53 | 54 | Assert.AreEqual(1, behaviour.oneEnter); 55 | Assert.AreEqual(1, behaviour.oneUpdate); 56 | Assert.AreEqual(1, behaviour.oneExit); 57 | Assert.AreEqual(1, behaviour.oneFinally); 58 | Assert.AreEqual(1, behaviour.twoEnter); 59 | Assert.AreEqual(0, behaviour.twoUpdate); //Only changed this frame, hasn't had a chance to update yet 60 | 61 | Assert.AreEqual(States.One, fsm.LastState); 62 | Assert.AreEqual(States.Two, fsm.State); 63 | Assert.AreEqual(States.Two, fsm.NextState); 64 | 65 | yield return null; 66 | 67 | Assert.AreEqual(1, behaviour.twoUpdate); //First update runs a frame later 68 | } 69 | 70 | [UnityTest] 71 | public IEnumerator TestChangeSameFrame() 72 | { 73 | fsm.ChangeState(States.One); 74 | fsm.ChangeState(States.Two); 75 | 76 | Assert.AreEqual(1, behaviour.oneEnter); 77 | Assert.AreEqual(0, behaviour.oneUpdate); //Update never has chance to fire during same frame change 78 | Assert.AreEqual(1, behaviour.oneExit); 79 | Assert.AreEqual(1, behaviour.oneFinally); 80 | Assert.AreEqual(1, behaviour.twoEnter); 81 | Assert.AreEqual(0, behaviour.twoUpdate); 82 | 83 | Assert.AreEqual(States.One, fsm.LastState); 84 | Assert.AreEqual(States.Two, fsm.State); 85 | Assert.AreEqual(States.Two, fsm.NextState); 86 | 87 | 88 | yield return null; 89 | 90 | Assert.AreEqual(0, behaviour.oneUpdate); 91 | Assert.AreEqual(1, behaviour.twoUpdate); //First frame runs in state two 92 | } 93 | 94 | private class StateClass : MonoBehaviour 95 | { 96 | public int oneEnter; 97 | public int oneUpdate; 98 | public int oneExit; 99 | public int oneFinally; 100 | 101 | public int twoEnter; 102 | public int twoUpdate; 103 | public int twoExit; 104 | public int twoFinally; 105 | 106 | public int threeEnter; 107 | public int threeUpdate; 108 | public int threeExit; 109 | public int threeFinally; 110 | 111 | public int fourEnter; 112 | public int fourUpdate; 113 | public int fourExit; 114 | public int fourFinally; 115 | 116 | void One_Enter() 117 | { 118 | Debug.LogFormat("State:{0} Frame:{1}", "One Enter", Time.frameCount); 119 | oneEnter++; 120 | } 121 | 122 | void One_Update() 123 | { 124 | Debug.LogFormat("State:{0} Frame:{1}", "One Update", Time.frameCount); 125 | oneUpdate++; 126 | } 127 | 128 | void One_Exit() 129 | { 130 | Debug.LogFormat("State:{0} Frame:{1}", "One Exit", Time.frameCount); 131 | oneExit++; 132 | } 133 | 134 | void One_Finally() 135 | { 136 | Debug.LogFormat("State:{0} Frame:{1}", "One Finally", Time.frameCount); 137 | oneFinally++; 138 | } 139 | 140 | void Two_Enter() 141 | { 142 | Debug.LogFormat("State:{0} Frame:{1}", "Two Enter", Time.frameCount); 143 | twoEnter++; 144 | } 145 | 146 | void Two_Update() 147 | { 148 | Debug.LogFormat("State:{0} Frame:{1}", "Two Update", Time.frameCount); 149 | twoUpdate++; 150 | } 151 | 152 | void Two_Exit() 153 | { 154 | Debug.LogFormat("State:{0} Frame:{1}", "Two Exit", Time.frameCount); 155 | twoExit++; 156 | } 157 | 158 | void Two_Finally() 159 | { 160 | Debug.LogFormat("State:{0} Frame:{1}", "Two Finally", Time.frameCount); 161 | twoFinally++; 162 | } 163 | 164 | void Three_Enter() 165 | { 166 | Debug.LogFormat("State:{0} Frame:{1}", "Three Enter", Time.frameCount); 167 | threeEnter++; 168 | } 169 | 170 | void Three_Update() 171 | { 172 | Debug.LogFormat("State:{0} Frame:{1}", "Three Update", Time.frameCount); 173 | threeUpdate++; 174 | } 175 | 176 | void Three_Exit() 177 | { 178 | Debug.LogFormat("State:{0} Frame:{1}", "Three Exit", Time.frameCount); 179 | threeExit++; 180 | } 181 | 182 | void Three_Finally() 183 | { 184 | Debug.LogFormat("State:{0} Frame:{1}", "Three Finally", Time.frameCount); 185 | threeFinally++; 186 | } 187 | 188 | void Four_Enter() 189 | { 190 | Debug.LogFormat("State:{0} Frame:{1}", "Four Enter", Time.frameCount); 191 | fourEnter++; 192 | } 193 | 194 | void Four_Update() 195 | { 196 | Debug.LogFormat("State:{0} Frame:{1}", "Four Update", Time.frameCount); 197 | fourUpdate++; 198 | } 199 | 200 | void Four_Exit() 201 | { 202 | Debug.LogFormat("State:{0} Frame:{1}", "Four Exit", Time.frameCount); 203 | fourExit++; 204 | } 205 | 206 | void Four_Finally() 207 | { 208 | Debug.LogFormat("State:{0} Frame:{1}", "Four Finally", Time.frameCount); 209 | fourFinally++; 210 | } 211 | } 212 | } 213 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Runtime/TestChangeState.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4306d2f2aa71459c9ea87a83001fd117 3 | timeCreated: 1567675903 -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Runtime/TestMonoBehaviourUpdates.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using MonsterLove.StateMachine; 3 | using NUnit.Framework; 4 | using UnityEngine; 5 | using UnityEngine.TestTools; 6 | 7 | namespace Tests 8 | { 9 | public class TestMonoBehaviourUpdates 10 | { 11 | public enum States 12 | { 13 | One, 14 | Two, 15 | Three, 16 | Four, 17 | } 18 | 19 | private GameObject go; 20 | private StateClass behaviour; 21 | private StateMachine fsm; 22 | 23 | [SetUp] 24 | public void Init() 25 | { 26 | go = new GameObject(); 27 | behaviour = go.AddComponent(); 28 | 29 | fsm = StateMachine.Initialize(behaviour); 30 | } 31 | 32 | [TearDown] 33 | public void Kill() 34 | { 35 | Object.Destroy(go); 36 | } 37 | 38 | [UnityTest] 39 | public IEnumerator TestUpdate() 40 | { 41 | fsm.ChangeState(States.One); 42 | 43 | yield return null; 44 | 45 | Assert.AreEqual(1, behaviour.oneEnter); 46 | Assert.AreEqual(1, behaviour.oneUpdate); 47 | Assert.AreEqual(1, behaviour.oneLateUpdate); 48 | 49 | yield return new WaitForSeconds(Time.fixedDeltaTime); 50 | 51 | Assert.GreaterOrEqual(behaviour.oneFixedUpdate, 1); 52 | } 53 | 54 | private class StateClass : MonoBehaviour 55 | { 56 | public int oneEnter; 57 | public int oneUpdate; 58 | public int oneFixedUpdate; 59 | public int oneLateUpdate; 60 | public int oneExit; 61 | public int oneFinally; 62 | 63 | void One_Enter() 64 | { 65 | Debug.LogFormat("State:{0} Frame:{1}", "One Enter", Time.frameCount); 66 | oneEnter++; 67 | } 68 | 69 | void One_FixedUpdate() 70 | { 71 | Debug.LogFormat("State:{0} Frame:{1}", "One FixedUpdate", Time.frameCount); 72 | oneFixedUpdate++; 73 | } 74 | 75 | void One_Update() 76 | { 77 | Debug.LogFormat("State:{0} Frame:{1}", "One Update", Time.frameCount); 78 | oneUpdate++; 79 | } 80 | 81 | void One_LateUpdate() 82 | { 83 | Debug.LogFormat("State:{0} Frame:{1}", "One Late Update", Time.frameCount); 84 | oneLateUpdate++; 85 | } 86 | 87 | void One_Exit() 88 | { 89 | Debug.LogFormat("State:{0} Frame:{1}", "One Exit", Time.frameCount); 90 | oneExit++; 91 | } 92 | 93 | void One_Finally() 94 | { 95 | Debug.LogFormat("State:{0} Frame:{1}", "One Finally", Time.frameCount); 96 | oneFinally++; 97 | } 98 | } 99 | } 100 | } -------------------------------------------------------------------------------- /StateMachine/Assets/MonsterLove/Tests/Runtime/TestMonoBehaviourUpdates.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 87d1cfcf5f33f2441b2b848c6053dbcf 3 | timeCreated: 1567675903 -------------------------------------------------------------------------------- /StateMachine/Packages/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.2d.sprite": "1.0.0", 4 | "com.unity.2d.tilemap": "1.0.0", 5 | "com.unity.ads": "3.6.1", 6 | "com.unity.analytics": "3.3.5", 7 | "com.unity.collab-proxy": "1.2.16", 8 | "com.unity.ide.rider": "1.1.4", 9 | "com.unity.ide.vscode": "1.2.3", 10 | "com.unity.multiplayer-hlapi": "1.0.8", 11 | "com.unity.purchasing": "2.2.1", 12 | "com.unity.test-framework": "1.1.20", 13 | "com.unity.textmeshpro": "2.0.1", 14 | "com.unity.timeline": "1.2.6", 15 | "com.unity.ugui": "1.0.0", 16 | "com.unity.xr.legacyinputhelpers": "2.1.7", 17 | "com.unity.modules.ai": "1.0.0", 18 | "com.unity.modules.androidjni": "1.0.0", 19 | "com.unity.modules.animation": "1.0.0", 20 | "com.unity.modules.assetbundle": "1.0.0", 21 | "com.unity.modules.audio": "1.0.0", 22 | "com.unity.modules.cloth": "1.0.0", 23 | "com.unity.modules.director": "1.0.0", 24 | "com.unity.modules.imageconversion": "1.0.0", 25 | "com.unity.modules.imgui": "1.0.0", 26 | "com.unity.modules.jsonserialize": "1.0.0", 27 | "com.unity.modules.particlesystem": "1.0.0", 28 | "com.unity.modules.physics": "1.0.0", 29 | "com.unity.modules.physics2d": "1.0.0", 30 | "com.unity.modules.screencapture": "1.0.0", 31 | "com.unity.modules.terrain": "1.0.0", 32 | "com.unity.modules.terrainphysics": "1.0.0", 33 | "com.unity.modules.tilemap": "1.0.0", 34 | "com.unity.modules.ui": "1.0.0", 35 | "com.unity.modules.uielements": "1.0.0", 36 | "com.unity.modules.umbra": "1.0.0", 37 | "com.unity.modules.unityanalytics": "1.0.0", 38 | "com.unity.modules.unitywebrequest": "1.0.0", 39 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 40 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 41 | "com.unity.modules.unitywebrequesttexture": "1.0.0", 42 | "com.unity.modules.unitywebrequestwww": "1.0.0", 43 | "com.unity.modules.vehicles": "1.0.0", 44 | "com.unity.modules.video": "1.0.0", 45 | "com.unity.modules.vr": "1.0.0", 46 | "com.unity.modules.wind": "1.0.0", 47 | "com.unity.modules.xr": "1.0.0" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /StateMachine/Packages/packages-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.2d.sprite": { 4 | "version": "1.0.0", 5 | "depth": 0, 6 | "source": "builtin", 7 | "dependencies": {} 8 | }, 9 | "com.unity.2d.tilemap": { 10 | "version": "1.0.0", 11 | "depth": 0, 12 | "source": "builtin", 13 | "dependencies": {} 14 | }, 15 | "com.unity.ads": { 16 | "version": "3.6.1", 17 | "depth": 0, 18 | "source": "registry", 19 | "dependencies": { 20 | "com.unity.ugui": "1.0.0" 21 | }, 22 | "url": "https://packages.unity.com" 23 | }, 24 | "com.unity.analytics": { 25 | "version": "3.3.5", 26 | "depth": 0, 27 | "source": "registry", 28 | "dependencies": { 29 | "com.unity.ugui": "1.0.0" 30 | }, 31 | "url": "https://packages.unity.com" 32 | }, 33 | "com.unity.collab-proxy": { 34 | "version": "1.2.16", 35 | "depth": 0, 36 | "source": "registry", 37 | "dependencies": {}, 38 | "url": "https://packages.unity.com" 39 | }, 40 | "com.unity.ext.nunit": { 41 | "version": "1.0.6", 42 | "depth": 1, 43 | "source": "registry", 44 | "dependencies": {}, 45 | "url": "https://packages.unity.com" 46 | }, 47 | "com.unity.ide.rider": { 48 | "version": "1.1.4", 49 | "depth": 0, 50 | "source": "registry", 51 | "dependencies": { 52 | "com.unity.test-framework": "1.1.1" 53 | }, 54 | "url": "https://packages.unity.com" 55 | }, 56 | "com.unity.ide.vscode": { 57 | "version": "1.2.3", 58 | "depth": 0, 59 | "source": "registry", 60 | "dependencies": {}, 61 | "url": "https://packages.unity.com" 62 | }, 63 | "com.unity.multiplayer-hlapi": { 64 | "version": "1.0.8", 65 | "depth": 0, 66 | "source": "registry", 67 | "dependencies": { 68 | "nuget.mono-cecil": "0.1.6-preview" 69 | }, 70 | "url": "https://packages.unity.com" 71 | }, 72 | "com.unity.purchasing": { 73 | "version": "2.2.1", 74 | "depth": 0, 75 | "source": "registry", 76 | "dependencies": { 77 | "com.unity.ugui": "1.0.0" 78 | }, 79 | "url": "https://packages.unity.com" 80 | }, 81 | "com.unity.test-framework": { 82 | "version": "1.1.20", 83 | "depth": 0, 84 | "source": "registry", 85 | "dependencies": { 86 | "com.unity.ext.nunit": "1.0.6", 87 | "com.unity.modules.imgui": "1.0.0", 88 | "com.unity.modules.jsonserialize": "1.0.0" 89 | }, 90 | "url": "https://packages.unity.com" 91 | }, 92 | "com.unity.textmeshpro": { 93 | "version": "2.0.1", 94 | "depth": 0, 95 | "source": "registry", 96 | "dependencies": { 97 | "com.unity.ugui": "1.0.0" 98 | }, 99 | "url": "https://packages.unity.com" 100 | }, 101 | "com.unity.timeline": { 102 | "version": "1.2.6", 103 | "depth": 0, 104 | "source": "registry", 105 | "dependencies": {}, 106 | "url": "https://packages.unity.com" 107 | }, 108 | "com.unity.ugui": { 109 | "version": "1.0.0", 110 | "depth": 0, 111 | "source": "builtin", 112 | "dependencies": { 113 | "com.unity.modules.ui": "1.0.0", 114 | "com.unity.modules.imgui": "1.0.0" 115 | } 116 | }, 117 | "com.unity.xr.legacyinputhelpers": { 118 | "version": "2.1.7", 119 | "depth": 0, 120 | "source": "registry", 121 | "dependencies": { 122 | "com.unity.modules.vr": "1.0.0", 123 | "com.unity.modules.xr": "1.0.0" 124 | }, 125 | "url": "https://packages.unity.com" 126 | }, 127 | "nuget.mono-cecil": { 128 | "version": "0.1.6-preview", 129 | "depth": 1, 130 | "source": "registry", 131 | "dependencies": {}, 132 | "url": "https://packages.unity.com" 133 | }, 134 | "com.unity.modules.ai": { 135 | "version": "1.0.0", 136 | "depth": 0, 137 | "source": "builtin", 138 | "dependencies": {} 139 | }, 140 | "com.unity.modules.androidjni": { 141 | "version": "1.0.0", 142 | "depth": 0, 143 | "source": "builtin", 144 | "dependencies": {} 145 | }, 146 | "com.unity.modules.animation": { 147 | "version": "1.0.0", 148 | "depth": 0, 149 | "source": "builtin", 150 | "dependencies": {} 151 | }, 152 | "com.unity.modules.assetbundle": { 153 | "version": "1.0.0", 154 | "depth": 0, 155 | "source": "builtin", 156 | "dependencies": {} 157 | }, 158 | "com.unity.modules.audio": { 159 | "version": "1.0.0", 160 | "depth": 0, 161 | "source": "builtin", 162 | "dependencies": {} 163 | }, 164 | "com.unity.modules.cloth": { 165 | "version": "1.0.0", 166 | "depth": 0, 167 | "source": "builtin", 168 | "dependencies": { 169 | "com.unity.modules.physics": "1.0.0" 170 | } 171 | }, 172 | "com.unity.modules.director": { 173 | "version": "1.0.0", 174 | "depth": 0, 175 | "source": "builtin", 176 | "dependencies": { 177 | "com.unity.modules.audio": "1.0.0", 178 | "com.unity.modules.animation": "1.0.0" 179 | } 180 | }, 181 | "com.unity.modules.imageconversion": { 182 | "version": "1.0.0", 183 | "depth": 0, 184 | "source": "builtin", 185 | "dependencies": {} 186 | }, 187 | "com.unity.modules.imgui": { 188 | "version": "1.0.0", 189 | "depth": 0, 190 | "source": "builtin", 191 | "dependencies": {} 192 | }, 193 | "com.unity.modules.jsonserialize": { 194 | "version": "1.0.0", 195 | "depth": 0, 196 | "source": "builtin", 197 | "dependencies": {} 198 | }, 199 | "com.unity.modules.particlesystem": { 200 | "version": "1.0.0", 201 | "depth": 0, 202 | "source": "builtin", 203 | "dependencies": {} 204 | }, 205 | "com.unity.modules.physics": { 206 | "version": "1.0.0", 207 | "depth": 0, 208 | "source": "builtin", 209 | "dependencies": {} 210 | }, 211 | "com.unity.modules.physics2d": { 212 | "version": "1.0.0", 213 | "depth": 0, 214 | "source": "builtin", 215 | "dependencies": {} 216 | }, 217 | "com.unity.modules.screencapture": { 218 | "version": "1.0.0", 219 | "depth": 0, 220 | "source": "builtin", 221 | "dependencies": { 222 | "com.unity.modules.imageconversion": "1.0.0" 223 | } 224 | }, 225 | "com.unity.modules.subsystems": { 226 | "version": "1.0.0", 227 | "depth": 1, 228 | "source": "builtin", 229 | "dependencies": { 230 | "com.unity.modules.jsonserialize": "1.0.0" 231 | } 232 | }, 233 | "com.unity.modules.terrain": { 234 | "version": "1.0.0", 235 | "depth": 0, 236 | "source": "builtin", 237 | "dependencies": {} 238 | }, 239 | "com.unity.modules.terrainphysics": { 240 | "version": "1.0.0", 241 | "depth": 0, 242 | "source": "builtin", 243 | "dependencies": { 244 | "com.unity.modules.physics": "1.0.0", 245 | "com.unity.modules.terrain": "1.0.0" 246 | } 247 | }, 248 | "com.unity.modules.tilemap": { 249 | "version": "1.0.0", 250 | "depth": 0, 251 | "source": "builtin", 252 | "dependencies": { 253 | "com.unity.modules.physics2d": "1.0.0" 254 | } 255 | }, 256 | "com.unity.modules.ui": { 257 | "version": "1.0.0", 258 | "depth": 0, 259 | "source": "builtin", 260 | "dependencies": {} 261 | }, 262 | "com.unity.modules.uielements": { 263 | "version": "1.0.0", 264 | "depth": 0, 265 | "source": "builtin", 266 | "dependencies": { 267 | "com.unity.modules.imgui": "1.0.0", 268 | "com.unity.modules.jsonserialize": "1.0.0" 269 | } 270 | }, 271 | "com.unity.modules.umbra": { 272 | "version": "1.0.0", 273 | "depth": 0, 274 | "source": "builtin", 275 | "dependencies": {} 276 | }, 277 | "com.unity.modules.unityanalytics": { 278 | "version": "1.0.0", 279 | "depth": 0, 280 | "source": "builtin", 281 | "dependencies": { 282 | "com.unity.modules.unitywebrequest": "1.0.0", 283 | "com.unity.modules.jsonserialize": "1.0.0" 284 | } 285 | }, 286 | "com.unity.modules.unitywebrequest": { 287 | "version": "1.0.0", 288 | "depth": 0, 289 | "source": "builtin", 290 | "dependencies": {} 291 | }, 292 | "com.unity.modules.unitywebrequestassetbundle": { 293 | "version": "1.0.0", 294 | "depth": 0, 295 | "source": "builtin", 296 | "dependencies": { 297 | "com.unity.modules.assetbundle": "1.0.0", 298 | "com.unity.modules.unitywebrequest": "1.0.0" 299 | } 300 | }, 301 | "com.unity.modules.unitywebrequestaudio": { 302 | "version": "1.0.0", 303 | "depth": 0, 304 | "source": "builtin", 305 | "dependencies": { 306 | "com.unity.modules.unitywebrequest": "1.0.0", 307 | "com.unity.modules.audio": "1.0.0" 308 | } 309 | }, 310 | "com.unity.modules.unitywebrequesttexture": { 311 | "version": "1.0.0", 312 | "depth": 0, 313 | "source": "builtin", 314 | "dependencies": { 315 | "com.unity.modules.unitywebrequest": "1.0.0", 316 | "com.unity.modules.imageconversion": "1.0.0" 317 | } 318 | }, 319 | "com.unity.modules.unitywebrequestwww": { 320 | "version": "1.0.0", 321 | "depth": 0, 322 | "source": "builtin", 323 | "dependencies": { 324 | "com.unity.modules.unitywebrequest": "1.0.0", 325 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 326 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 327 | "com.unity.modules.audio": "1.0.0", 328 | "com.unity.modules.assetbundle": "1.0.0", 329 | "com.unity.modules.imageconversion": "1.0.0" 330 | } 331 | }, 332 | "com.unity.modules.vehicles": { 333 | "version": "1.0.0", 334 | "depth": 0, 335 | "source": "builtin", 336 | "dependencies": { 337 | "com.unity.modules.physics": "1.0.0" 338 | } 339 | }, 340 | "com.unity.modules.video": { 341 | "version": "1.0.0", 342 | "depth": 0, 343 | "source": "builtin", 344 | "dependencies": { 345 | "com.unity.modules.audio": "1.0.0", 346 | "com.unity.modules.ui": "1.0.0", 347 | "com.unity.modules.unitywebrequest": "1.0.0" 348 | } 349 | }, 350 | "com.unity.modules.vr": { 351 | "version": "1.0.0", 352 | "depth": 0, 353 | "source": "builtin", 354 | "dependencies": { 355 | "com.unity.modules.jsonserialize": "1.0.0", 356 | "com.unity.modules.physics": "1.0.0", 357 | "com.unity.modules.xr": "1.0.0" 358 | } 359 | }, 360 | "com.unity.modules.wind": { 361 | "version": "1.0.0", 362 | "depth": 0, 363 | "source": "builtin", 364 | "dependencies": {} 365 | }, 366 | "com.unity.modules.xr": { 367 | "version": "1.0.0", 368 | "depth": 0, 369 | "source": "builtin", 370 | "dependencies": { 371 | "com.unity.modules.physics": "1.0.0", 372 | "com.unity.modules.jsonserialize": "1.0.0", 373 | "com.unity.modules.subsystems": "1.0.0" 374 | } 375 | } 376 | } 377 | } 378 | -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | m_Volume: 1 7 | Rolloff Scale: 1 8 | Doppler Factor: 1 9 | Default Speaker Mode: 2 10 | m_SampleRate: 0 11 | m_DSPBufferSize: 1024 12 | m_VirtualVoiceCount: 512 13 | m_RealVoiceCount: 32 14 | m_SpatializerPlugin: 15 | m_AmbisonicDecoderPlugin: 16 | m_DisableAudio: 0 17 | m_VirtualizeEffects: 1 18 | -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!236 &1 4 | ClusterInputManager: 5 | m_ObjectHideFlags: 0 6 | m_Inputs: [] 7 | -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 10 7 | m_Gravity: {x: 0, y: -9.81, z: 0} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_BounceThreshold: 2 10 | m_SleepThreshold: 0.005 11 | m_DefaultContactOffset: 0.01 12 | m_DefaultSolverIterations: 6 13 | m_DefaultSolverVelocityIterations: 1 14 | m_QueriesHitBackfaces: 0 15 | m_QueriesHitTriggers: 1 16 | m_EnableAdaptiveForce: 0 17 | m_ClothInterCollisionDistance: 0 18 | m_ClothInterCollisionStiffness: 0 19 | m_ContactsGeneration: 1 20 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 21 | m_AutoSimulation: 1 22 | m_AutoSyncTransforms: 1 23 | m_ReuseCollisionCallbacks: 0 24 | m_ClothInterCollisionSettingsToggle: 0 25 | m_ContactPairsMode: 0 26 | m_BroadphaseType: 0 27 | m_WorldBounds: 28 | m_Center: {x: 0, y: 0, z: 0} 29 | m_Extent: {x: 250, y: 250, z: 250} 30 | m_WorldSubdivisions: 8 31 | m_FrictionType: 0 32 | m_EnableEnhancedDeterminism: 0 33 | m_EnableUnifiedHeightmaps: 1 34 | -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: 8 | - enabled: 1 9 | path: Assets/MonsterLove/Samples/StateMachine_Advanced.unity 10 | guid: fa60728e35284674e88aa2ae6df84576 11 | m_configObjects: {} 12 | -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 7 7 | m_ExternalVersionControlSupport: Visible Meta Files 8 | m_SerializationMode: 2 9 | m_LineEndingsForNewScripts: 1 10 | m_DefaultBehaviorMode: 0 11 | m_PrefabRegularEnvironment: {fileID: 0} 12 | m_PrefabUIEnvironment: {fileID: 0} 13 | m_SpritePackerMode: 2 14 | m_SpritePackerPaddingPower: 1 15 | m_EtcTextureCompressorBehavior: 0 16 | m_EtcTextureFastCompressor: 2 17 | m_EtcTextureNormalCompressor: 2 18 | m_EtcTextureBestCompressor: 5 19 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp 20 | m_ProjectGenerationRootNamespace: 21 | m_CollabEditorSettings: 22 | inProgressEnabled: 1 23 | m_EnableTextureStreamingInPlayMode: 1 24 | -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 13 7 | m_Deferred: 8 | m_Mode: 1 9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} 10 | m_DeferredReflections: 11 | m_Mode: 1 12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} 13 | m_ScreenSpaceShadows: 14 | m_Mode: 1 15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} 16 | m_LegacyDeferred: 17 | m_Mode: 1 18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} 19 | m_DepthNormals: 20 | m_Mode: 1 21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} 22 | m_MotionVectors: 23 | m_Mode: 1 24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} 25 | m_LightHalo: 26 | m_Mode: 1 27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} 28 | m_LensFlare: 29 | m_Mode: 1 30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} 31 | m_AlwaysIncludedShaders: 32 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 33 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} 34 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} 35 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} 36 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} 37 | - {fileID: 10782, guid: 0000000000000000f000000000000000, type: 0} 38 | - {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0} 39 | - {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0} 40 | - {fileID: 16001, guid: 0000000000000000f000000000000000, type: 0} 41 | m_PreloadedShaders: [] 42 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, 43 | type: 0} 44 | m_CustomRenderPipeline: {fileID: 0} 45 | m_TransparencySortMode: 0 46 | m_TransparencySortAxis: {x: 0, y: 0, z: 1} 47 | m_DefaultRenderingPath: 1 48 | m_DefaultMobileRenderingPath: 1 49 | m_TierSettings: [] 50 | m_LightmapStripping: 0 51 | m_FogStripping: 0 52 | m_InstancingStripping: 0 53 | m_LightmapKeepPlain: 1 54 | m_LightmapKeepDirCombined: 1 55 | m_LightmapKeepDynamicPlain: 1 56 | m_LightmapKeepDynamicDirCombined: 1 57 | m_LightmapKeepShadowMask: 1 58 | m_LightmapKeepSubtractive: 1 59 | m_FogKeepLinear: 1 60 | m_FogKeepExp: 1 61 | m_FogKeepExp2: 1 62 | m_AlbedoSwatchInfos: [] 63 | m_LightsUseLinearIntensity: 0 64 | m_LightsUseColorTemperature: 0 65 | m_LogWhenShaderIsCompiled: 0 66 | m_AllowEnlightenSupportForUpgradedProject: 1 67 | -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!13 &1 4 | InputManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Axes: 8 | - serializedVersion: 3 9 | m_Name: Horizontal 10 | descriptiveName: 11 | descriptiveNegativeName: 12 | negativeButton: left 13 | positiveButton: right 14 | altNegativeButton: a 15 | altPositiveButton: d 16 | gravity: 3 17 | dead: 0.001 18 | sensitivity: 3 19 | snap: 1 20 | invert: 0 21 | type: 0 22 | axis: 0 23 | joyNum: 0 24 | - serializedVersion: 3 25 | m_Name: Vertical 26 | descriptiveName: 27 | descriptiveNegativeName: 28 | negativeButton: down 29 | positiveButton: up 30 | altNegativeButton: s 31 | altPositiveButton: w 32 | gravity: 3 33 | dead: 0.001 34 | sensitivity: 3 35 | snap: 1 36 | invert: 0 37 | type: 0 38 | axis: 0 39 | joyNum: 0 40 | - serializedVersion: 3 41 | m_Name: Fire1 42 | descriptiveName: 43 | descriptiveNegativeName: 44 | negativeButton: 45 | positiveButton: left ctrl 46 | altNegativeButton: 47 | altPositiveButton: mouse 0 48 | gravity: 1000 49 | dead: 0.001 50 | sensitivity: 1000 51 | snap: 0 52 | invert: 0 53 | type: 0 54 | axis: 0 55 | joyNum: 0 56 | - serializedVersion: 3 57 | m_Name: Fire2 58 | descriptiveName: 59 | descriptiveNegativeName: 60 | negativeButton: 61 | positiveButton: left alt 62 | altNegativeButton: 63 | altPositiveButton: mouse 1 64 | gravity: 1000 65 | dead: 0.001 66 | sensitivity: 1000 67 | snap: 0 68 | invert: 0 69 | type: 0 70 | axis: 0 71 | joyNum: 0 72 | - serializedVersion: 3 73 | m_Name: Fire3 74 | descriptiveName: 75 | descriptiveNegativeName: 76 | negativeButton: 77 | positiveButton: left cmd 78 | altNegativeButton: 79 | altPositiveButton: mouse 2 80 | gravity: 1000 81 | dead: 0.001 82 | sensitivity: 1000 83 | snap: 0 84 | invert: 0 85 | type: 0 86 | axis: 0 87 | joyNum: 0 88 | - serializedVersion: 3 89 | m_Name: Jump 90 | descriptiveName: 91 | descriptiveNegativeName: 92 | negativeButton: 93 | positiveButton: space 94 | altNegativeButton: 95 | altPositiveButton: 96 | gravity: 1000 97 | dead: 0.001 98 | sensitivity: 1000 99 | snap: 0 100 | invert: 0 101 | type: 0 102 | axis: 0 103 | joyNum: 0 104 | - serializedVersion: 3 105 | m_Name: Mouse X 106 | descriptiveName: 107 | descriptiveNegativeName: 108 | negativeButton: 109 | positiveButton: 110 | altNegativeButton: 111 | altPositiveButton: 112 | gravity: 0 113 | dead: 0 114 | sensitivity: 0.1 115 | snap: 0 116 | invert: 0 117 | type: 1 118 | axis: 0 119 | joyNum: 0 120 | - serializedVersion: 3 121 | m_Name: Mouse Y 122 | descriptiveName: 123 | descriptiveNegativeName: 124 | negativeButton: 125 | positiveButton: 126 | altNegativeButton: 127 | altPositiveButton: 128 | gravity: 0 129 | dead: 0 130 | sensitivity: 0.1 131 | snap: 0 132 | invert: 0 133 | type: 1 134 | axis: 1 135 | joyNum: 0 136 | - serializedVersion: 3 137 | m_Name: Mouse ScrollWheel 138 | descriptiveName: 139 | descriptiveNegativeName: 140 | negativeButton: 141 | positiveButton: 142 | altNegativeButton: 143 | altPositiveButton: 144 | gravity: 0 145 | dead: 0 146 | sensitivity: 0.1 147 | snap: 0 148 | invert: 0 149 | type: 1 150 | axis: 2 151 | joyNum: 0 152 | - serializedVersion: 3 153 | m_Name: Horizontal 154 | descriptiveName: 155 | descriptiveNegativeName: 156 | negativeButton: 157 | positiveButton: 158 | altNegativeButton: 159 | altPositiveButton: 160 | gravity: 0 161 | dead: 0.19 162 | sensitivity: 1 163 | snap: 0 164 | invert: 0 165 | type: 2 166 | axis: 0 167 | joyNum: 0 168 | - serializedVersion: 3 169 | m_Name: Vertical 170 | descriptiveName: 171 | descriptiveNegativeName: 172 | negativeButton: 173 | positiveButton: 174 | altNegativeButton: 175 | altPositiveButton: 176 | gravity: 0 177 | dead: 0.19 178 | sensitivity: 1 179 | snap: 0 180 | invert: 1 181 | type: 2 182 | axis: 1 183 | joyNum: 0 184 | - serializedVersion: 3 185 | m_Name: Fire1 186 | descriptiveName: 187 | descriptiveNegativeName: 188 | negativeButton: 189 | positiveButton: joystick button 0 190 | altNegativeButton: 191 | altPositiveButton: 192 | gravity: 1000 193 | dead: 0.001 194 | sensitivity: 1000 195 | snap: 0 196 | invert: 0 197 | type: 0 198 | axis: 0 199 | joyNum: 0 200 | - serializedVersion: 3 201 | m_Name: Fire2 202 | descriptiveName: 203 | descriptiveNegativeName: 204 | negativeButton: 205 | positiveButton: joystick button 1 206 | altNegativeButton: 207 | altPositiveButton: 208 | gravity: 1000 209 | dead: 0.001 210 | sensitivity: 1000 211 | snap: 0 212 | invert: 0 213 | type: 0 214 | axis: 0 215 | joyNum: 0 216 | - serializedVersion: 3 217 | m_Name: Fire3 218 | descriptiveName: 219 | descriptiveNegativeName: 220 | negativeButton: 221 | positiveButton: joystick button 2 222 | altNegativeButton: 223 | altPositiveButton: 224 | gravity: 1000 225 | dead: 0.001 226 | sensitivity: 1000 227 | snap: 0 228 | invert: 0 229 | type: 0 230 | axis: 0 231 | joyNum: 0 232 | - serializedVersion: 3 233 | m_Name: Jump 234 | descriptiveName: 235 | descriptiveNegativeName: 236 | negativeButton: 237 | positiveButton: joystick button 3 238 | altNegativeButton: 239 | altPositiveButton: 240 | gravity: 1000 241 | dead: 0.001 242 | sensitivity: 1000 243 | snap: 0 244 | invert: 0 245 | type: 0 246 | axis: 0 247 | joyNum: 0 248 | - serializedVersion: 3 249 | m_Name: Submit 250 | descriptiveName: 251 | descriptiveNegativeName: 252 | negativeButton: 253 | positiveButton: return 254 | altNegativeButton: 255 | altPositiveButton: joystick button 0 256 | gravity: 1000 257 | dead: 0.001 258 | sensitivity: 1000 259 | snap: 0 260 | invert: 0 261 | type: 0 262 | axis: 0 263 | joyNum: 0 264 | - serializedVersion: 3 265 | m_Name: Submit 266 | descriptiveName: 267 | descriptiveNegativeName: 268 | negativeButton: 269 | positiveButton: enter 270 | altNegativeButton: 271 | altPositiveButton: space 272 | gravity: 1000 273 | dead: 0.001 274 | sensitivity: 1000 275 | snap: 0 276 | invert: 0 277 | type: 0 278 | axis: 0 279 | joyNum: 0 280 | - serializedVersion: 3 281 | m_Name: Cancel 282 | descriptiveName: 283 | descriptiveNegativeName: 284 | negativeButton: 285 | positiveButton: escape 286 | altNegativeButton: 287 | altPositiveButton: joystick button 1 288 | gravity: 1000 289 | dead: 0.001 290 | sensitivity: 1000 291 | snap: 0 292 | invert: 0 293 | type: 0 294 | axis: 0 295 | joyNum: 0 296 | -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshProjectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | areas: 8 | - name: Walkable 9 | cost: 1 10 | - name: Not Walkable 11 | cost: 1 12 | - name: Jump 13 | cost: 2 14 | - name: 15 | cost: 1 16 | - name: 17 | cost: 1 18 | - name: 19 | cost: 1 20 | - name: 21 | cost: 1 22 | - name: 23 | cost: 1 24 | - name: 25 | cost: 1 26 | - name: 27 | cost: 1 28 | - name: 29 | cost: 1 30 | - name: 31 | cost: 1 32 | - name: 33 | cost: 1 34 | - name: 35 | cost: 1 36 | - name: 37 | cost: 1 38 | - name: 39 | cost: 1 40 | - name: 41 | cost: 1 42 | - name: 43 | cost: 1 44 | - name: 45 | cost: 1 46 | - name: 47 | cost: 1 48 | - name: 49 | cost: 1 50 | - name: 51 | cost: 1 52 | - name: 53 | cost: 1 54 | - name: 55 | cost: 1 56 | - name: 57 | cost: 1 58 | - name: 59 | cost: 1 60 | - name: 61 | cost: 1 62 | - name: 63 | cost: 1 64 | - name: 65 | cost: 1 66 | - name: 67 | cost: 1 68 | - name: 69 | cost: 1 70 | - name: 71 | cost: 1 72 | m_LastAgentTypeID: -887442657 73 | m_Settings: 74 | - serializedVersion: 2 75 | agentTypeID: 0 76 | agentRadius: 0.5 77 | agentHeight: 2 78 | agentSlope: 45 79 | agentClimb: 0.75 80 | ledgeDropHeight: 0 81 | maxJumpAcrossDistance: 0 82 | minRegionArea: 2 83 | manualCellSize: 0 84 | cellSize: 0.16666667 85 | manualTileSize: 0 86 | tileSize: 256 87 | accuratePlacement: 0 88 | debug: 89 | m_Flags: 0 90 | m_SettingNames: 91 | - Humanoid 92 | -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/NavMeshLayers.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thefuntastic/Unity3d-Finite-State-Machine/90357e28aa12fdd89f7945b62aa7c2bc20c72c29/StateMachine/ProjectSettings/NavMeshLayers.asset -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thefuntastic/Unity3d-Finite-State-Machine/90357e28aa12fdd89f7945b62aa7c2bc20c72c29/StateMachine/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/PackageManagerSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &1 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 61 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0} 13 | m_Name: 14 | m_EditorClassIdentifier: 15 | m_ScopedRegistriesSettingsExpanded: 1 16 | oneTimeWarningShown: 0 17 | m_Registries: 18 | - m_Id: main 19 | m_Name: 20 | m_Url: https://packages.unity.com 21 | m_Scopes: [] 22 | m_IsDefault: 1 23 | m_UserSelectedRegistryName: 24 | m_UserAddingNewScopedRegistry: 0 25 | m_RegistryInfoDraft: 26 | m_ErrorMessage: 27 | m_Original: 28 | m_Id: 29 | m_Name: 30 | m_Url: 31 | m_Scopes: [] 32 | m_IsDefault: 0 33 | m_Modified: 0 34 | m_Name: 35 | m_Url: 36 | m_Scopes: 37 | - 38 | m_SelectedScopeIndex: 0 39 | -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 4 7 | m_Gravity: {x: 0, y: -9.81} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_VelocityIterations: 8 10 | m_PositionIterations: 3 11 | m_VelocityThreshold: 1 12 | m_MaxLinearCorrection: 0.2 13 | m_MaxAngularCorrection: 8 14 | m_MaxTranslationSpeed: 100 15 | m_MaxRotationSpeed: 360 16 | m_BaumgarteScale: 0.2 17 | m_BaumgarteTimeOfImpactScale: 0.75 18 | m_TimeToSleep: 0.5 19 | m_LinearSleepTolerance: 0.01 20 | m_AngularSleepTolerance: 2 21 | m_DefaultContactOffset: 0.01 22 | m_JobOptions: 23 | serializedVersion: 2 24 | useMultithreading: 0 25 | useConsistencySorting: 0 26 | m_InterpolationPosesPerJob: 100 27 | m_NewContactsPerJob: 30 28 | m_CollideContactsPerJob: 100 29 | m_ClearFlagsPerJob: 200 30 | m_ClearBodyForcesPerJob: 200 31 | m_SyncDiscreteFixturesPerJob: 50 32 | m_SyncContinuousFixturesPerJob: 50 33 | m_FindNearestContactsPerJob: 100 34 | m_UpdateTriggerContactsPerJob: 100 35 | m_IslandSolverCostThreshold: 100 36 | m_IslandSolverBodyCostScale: 1 37 | m_IslandSolverContactCostScale: 10 38 | m_IslandSolverJointCostScale: 10 39 | m_IslandSolverBodiesPerJob: 50 40 | m_IslandSolverContactsPerJob: 50 41 | m_AutoSimulation: 1 42 | m_QueriesHitTriggers: 1 43 | m_QueriesStartInColliders: 1 44 | m_CallbacksOnDisable: 1 45 | m_ReuseCollisionCallbacks: 0 46 | m_AutoSyncTransforms: 1 47 | m_AlwaysShowColliders: 0 48 | m_ShowColliderSleep: 1 49 | m_ShowColliderContacts: 0 50 | m_ShowColliderAABB: 0 51 | m_ContactArrowScale: 0.2 52 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} 53 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} 54 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} 55 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} 56 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 57 | -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/PresetManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1386491679 &1 4 | PresetManager: 5 | m_ObjectHideFlags: 0 6 | m_DefaultList: [] 7 | -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2019.4.19f1 2 | m_EditorVersionWithRevision: 2019.4.19f1 (ca5b14067cec) 3 | -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!47 &1 4 | QualitySettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_CurrentQuality: 3 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: Fastest 11 | pixelLightCount: 0 12 | shadows: 0 13 | shadowResolution: 0 14 | shadowProjection: 1 15 | shadowCascades: 1 16 | shadowDistance: 15 17 | shadowNearPlaneOffset: 2 18 | shadowCascade2Split: 0.33333334 19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 20 | shadowmaskMode: 0 21 | blendWeights: 1 22 | textureQuality: 1 23 | anisotropicTextures: 0 24 | antiAliasing: 0 25 | softParticles: 0 26 | softVegetation: 0 27 | realtimeReflectionProbes: 0 28 | billboardsFaceCameraPosition: 0 29 | vSyncCount: 0 30 | lodBias: 0.3 31 | maximumLODLevel: 0 32 | streamingMipmapsActive: 0 33 | streamingMipmapsAddAllCameras: 1 34 | streamingMipmapsMemoryBudget: 512 35 | streamingMipmapsRenderersPerFrame: 512 36 | streamingMipmapsMaxLevelReduction: 2 37 | streamingMipmapsMaxFileIORequests: 1024 38 | particleRaycastBudget: 4 39 | asyncUploadTimeSlice: 2 40 | asyncUploadBufferSize: 4 41 | asyncUploadPersistentBuffer: 1 42 | resolutionScalingFixedDPIFactor: 1 43 | excludedTargetPlatforms: [] 44 | - serializedVersion: 2 45 | name: Fast 46 | pixelLightCount: 0 47 | shadows: 0 48 | shadowResolution: 0 49 | shadowProjection: 1 50 | shadowCascades: 1 51 | shadowDistance: 20 52 | shadowNearPlaneOffset: 2 53 | shadowCascade2Split: 0.33333334 54 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 55 | shadowmaskMode: 0 56 | blendWeights: 2 57 | textureQuality: 0 58 | anisotropicTextures: 0 59 | antiAliasing: 0 60 | softParticles: 0 61 | softVegetation: 0 62 | realtimeReflectionProbes: 0 63 | billboardsFaceCameraPosition: 0 64 | vSyncCount: 0 65 | lodBias: 0.4 66 | maximumLODLevel: 0 67 | streamingMipmapsActive: 0 68 | streamingMipmapsAddAllCameras: 1 69 | streamingMipmapsMemoryBudget: 512 70 | streamingMipmapsRenderersPerFrame: 512 71 | streamingMipmapsMaxLevelReduction: 2 72 | streamingMipmapsMaxFileIORequests: 1024 73 | particleRaycastBudget: 16 74 | asyncUploadTimeSlice: 2 75 | asyncUploadBufferSize: 4 76 | asyncUploadPersistentBuffer: 1 77 | resolutionScalingFixedDPIFactor: 1 78 | excludedTargetPlatforms: [] 79 | - serializedVersion: 2 80 | name: Simple 81 | pixelLightCount: 1 82 | shadows: 1 83 | shadowResolution: 0 84 | shadowProjection: 1 85 | shadowCascades: 1 86 | shadowDistance: 20 87 | shadowNearPlaneOffset: 2 88 | shadowCascade2Split: 0.33333334 89 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 90 | shadowmaskMode: 0 91 | blendWeights: 2 92 | textureQuality: 0 93 | anisotropicTextures: 1 94 | antiAliasing: 0 95 | softParticles: 0 96 | softVegetation: 0 97 | realtimeReflectionProbes: 0 98 | billboardsFaceCameraPosition: 0 99 | vSyncCount: 0 100 | lodBias: 0.7 101 | maximumLODLevel: 0 102 | streamingMipmapsActive: 0 103 | streamingMipmapsAddAllCameras: 1 104 | streamingMipmapsMemoryBudget: 512 105 | streamingMipmapsRenderersPerFrame: 512 106 | streamingMipmapsMaxLevelReduction: 2 107 | streamingMipmapsMaxFileIORequests: 1024 108 | particleRaycastBudget: 64 109 | asyncUploadTimeSlice: 2 110 | asyncUploadBufferSize: 4 111 | asyncUploadPersistentBuffer: 1 112 | resolutionScalingFixedDPIFactor: 1 113 | excludedTargetPlatforms: [] 114 | - serializedVersion: 2 115 | name: Good 116 | pixelLightCount: 2 117 | shadows: 2 118 | shadowResolution: 1 119 | shadowProjection: 1 120 | shadowCascades: 2 121 | shadowDistance: 40 122 | shadowNearPlaneOffset: 2 123 | shadowCascade2Split: 0.33333334 124 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 125 | shadowmaskMode: 1 126 | blendWeights: 2 127 | textureQuality: 0 128 | anisotropicTextures: 1 129 | antiAliasing: 0 130 | softParticles: 0 131 | softVegetation: 1 132 | realtimeReflectionProbes: 1 133 | billboardsFaceCameraPosition: 1 134 | vSyncCount: 1 135 | lodBias: 1 136 | maximumLODLevel: 0 137 | streamingMipmapsActive: 0 138 | streamingMipmapsAddAllCameras: 1 139 | streamingMipmapsMemoryBudget: 512 140 | streamingMipmapsRenderersPerFrame: 512 141 | streamingMipmapsMaxLevelReduction: 2 142 | streamingMipmapsMaxFileIORequests: 1024 143 | particleRaycastBudget: 256 144 | asyncUploadTimeSlice: 2 145 | asyncUploadBufferSize: 4 146 | asyncUploadPersistentBuffer: 1 147 | resolutionScalingFixedDPIFactor: 1 148 | excludedTargetPlatforms: [] 149 | - serializedVersion: 2 150 | name: Beautiful 151 | pixelLightCount: 3 152 | shadows: 2 153 | shadowResolution: 2 154 | shadowProjection: 1 155 | shadowCascades: 2 156 | shadowDistance: 70 157 | shadowNearPlaneOffset: 2 158 | shadowCascade2Split: 0.33333334 159 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 160 | shadowmaskMode: 1 161 | blendWeights: 4 162 | textureQuality: 0 163 | anisotropicTextures: 2 164 | antiAliasing: 2 165 | softParticles: 1 166 | softVegetation: 1 167 | realtimeReflectionProbes: 1 168 | billboardsFaceCameraPosition: 1 169 | vSyncCount: 1 170 | lodBias: 1.5 171 | maximumLODLevel: 0 172 | streamingMipmapsActive: 0 173 | streamingMipmapsAddAllCameras: 1 174 | streamingMipmapsMemoryBudget: 512 175 | streamingMipmapsRenderersPerFrame: 512 176 | streamingMipmapsMaxLevelReduction: 2 177 | streamingMipmapsMaxFileIORequests: 1024 178 | particleRaycastBudget: 1024 179 | asyncUploadTimeSlice: 2 180 | asyncUploadBufferSize: 4 181 | asyncUploadPersistentBuffer: 1 182 | resolutionScalingFixedDPIFactor: 1 183 | excludedTargetPlatforms: [] 184 | - serializedVersion: 2 185 | name: Fantastic 186 | pixelLightCount: 4 187 | shadows: 2 188 | shadowResolution: 2 189 | shadowProjection: 1 190 | shadowCascades: 4 191 | shadowDistance: 150 192 | shadowNearPlaneOffset: 2 193 | shadowCascade2Split: 0.33333334 194 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 195 | shadowmaskMode: 1 196 | blendWeights: 4 197 | textureQuality: 0 198 | anisotropicTextures: 2 199 | antiAliasing: 2 200 | softParticles: 1 201 | softVegetation: 1 202 | realtimeReflectionProbes: 1 203 | billboardsFaceCameraPosition: 1 204 | vSyncCount: 1 205 | lodBias: 2 206 | maximumLODLevel: 0 207 | streamingMipmapsActive: 0 208 | streamingMipmapsAddAllCameras: 1 209 | streamingMipmapsMemoryBudget: 512 210 | streamingMipmapsRenderersPerFrame: 512 211 | streamingMipmapsMaxLevelReduction: 2 212 | streamingMipmapsMaxFileIORequests: 1024 213 | particleRaycastBudget: 4096 214 | asyncUploadTimeSlice: 2 215 | asyncUploadBufferSize: 4 216 | asyncUploadPersistentBuffer: 1 217 | resolutionScalingFixedDPIFactor: 1 218 | excludedTargetPlatforms: [] 219 | m_PerPlatformDefaultQuality: {} 220 | -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | serializedVersion: 2 6 | tags: [] 7 | layers: 8 | - Default 9 | - TransparentFX 10 | - Ignore Raycast 11 | - 12 | - Water 13 | - UI 14 | - 15 | - 16 | - 17 | - 18 | - 19 | - 20 | - 21 | - 22 | - 23 | - 24 | - 25 | - 26 | - 27 | - 28 | - 29 | - 30 | - 31 | - 32 | - 33 | - 34 | - 35 | - 36 | - 37 | - 38 | - 39 | - 40 | m_SortingLayers: 41 | - name: Default 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: 0.02 7 | Maximum Allowed Timestep: 0.33333334 8 | m_TimeScale: 1 9 | Maximum Particle Timestep: 0.03 10 | -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!310 &1 4 | UnityConnectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 1 7 | m_Enabled: 0 8 | m_TestMode: 0 9 | m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events 10 | m_EventUrl: https://cdp.cloud.unity3d.com/v1/events 11 | m_ConfigUrl: https://config.uca.cloud.unity3d.com 12 | m_TestInitMode: 0 13 | CrashReportingSettings: 14 | m_EventUrl: https://perf-events.cloud.unity3d.com 15 | m_Enabled: 0 16 | m_LogBufferSize: 10 17 | m_CaptureEditorExceptions: 1 18 | UnityPurchasingSettings: 19 | m_Enabled: 0 20 | m_TestMode: 0 21 | UnityAnalyticsSettings: 22 | m_Enabled: 0 23 | m_TestMode: 0 24 | m_InitializeOnStartup: 1 25 | UnityAdsSettings: 26 | m_Enabled: 0 27 | m_InitializeOnStartup: 1 28 | m_TestMode: 0 29 | m_IosGameId: 30 | m_AndroidGameId: 31 | m_GameIds: {} 32 | m_GameId: 33 | PerformanceReportingSettings: 34 | m_Enabled: 0 35 | -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/VFXManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!937362698 &1 4 | VFXManager: 5 | m_ObjectHideFlags: 0 6 | m_IndirectShader: {fileID: 0} 7 | m_CopyBufferShader: {fileID: 0} 8 | m_SortShader: {fileID: 0} 9 | m_RenderPipeSettingsPath: 10 | m_FixedTimeStep: 0.016666668 11 | m_MaxDeltaTime: 0.05 12 | -------------------------------------------------------------------------------- /StateMachine/ProjectSettings/XRSettings.asset: -------------------------------------------------------------------------------- 1 | { 2 | "m_SettingKeys": [ 3 | "VR Device Disabled", 4 | "VR Device User Alert" 5 | ], 6 | "m_SettingValues": [ 7 | "False", 8 | "False" 9 | ] 10 | } -------------------------------------------------------------------------------- /changelog.txt: -------------------------------------------------------------------------------- 1 | v4.0 April 2021 2 | *StateMachine now accepts a Driver class, a powerful convention for data driven state events that provides explicit control of the State Machine lifecycle. 3 | *Added `LastState` property 4 | *Added `NextState` property 5 | *Added `reenter` flag to allow transitions back into the same state 6 | *Fixed AOT imcompatibility preventing release of v4.0 7 | *Added new example showing Driver implementation 8 | *Modernised unit tests for Unity Test Runner 9 | *Components deriving from a super class will now also search super classes for state methods 10 | *Upgraded project to Unity 2019.4.19 11 | 12 | ### Upgrade Notes: 13 | The layout of the library has changed. To avoid issues delete the existing `MonsterLove` folder containing `StateMachine.cs` and related files, before reimporting the Unity package. The API however remains backwards compatible with prior versions. This means your client code does not need to be upgraded. 14 | 15 | v4.0-rc1 August 2019 16 | *Created StateMachine Driver concept 17 | *Added `LastState` property to StateMachine class 18 | *Modernised unit tests for Unity Test Runner 19 | *Compenents deriving from a super class will now also search super classes for state methods 20 | *Upgraded project to Unity 2018.3.7 21 | 22 | v3.1 March 2016 23 | *Fixing edge cases where non coroutine Exit fucntions wouldn't be called if StateTrasition.Overwrite used 24 | 25 | v3.0 March 2016 26 | *Multiple state machines per game object now supported 27 | *Can now reference stateMachine.State without having to cast the result to an enum 28 | *Enter and Exit methods that aren't corouintes are now executed on the same frame they are called - solves many timing issues 29 | *StateMachine is assigned to an instance variable rather than inheritance. Means your MonoBehaviour can inherit from other classes and allows multiple state machines per object 30 | *Classes are now StateMachine and StateMachineRunner. Is more semantic and provides a gentle upgrade path that won't clash with the previous implementation 31 | *StateManchine.Initialize(component) syntax sugar to make initialization more friendly 32 | *Enhanced test coverage 33 | *Removed Method Name warnings as this was just an un-ending source of grief 34 | *Upgraded example project to Unity 5.3.2 35 | 36 | v2.4 June 2015 37 | *Bugfix: StateTransition.Overwrite is now consistent with expected behviour 38 | *Added "Finally" state function that is always called, even if overwrite cancels the exit routine 39 | 40 | v2.3 April 2015 41 | *Breaking change: Refactored StateMachineBehaviour and StateMachineEngine to StateBehaviour and StateEngine to avoid Unity5 conflicts 42 | *Added the concept of StateTransition. Two options: Safe and Overwrite. The default is safe which allows the current coroutine to finish before changing to the next state. 43 | *Better test coverage using UnityTestTools integration tests 44 | 45 | v2.2 January 2015 46 | *State Update & Late Update functions no longer run during transitions (i.e. Enter & Exit functions) 47 | *Bug fix: Changing state from a states Update function no longer cause states to enter twice. Note: changing from functions outside of a state can still cause this behaviour 48 | 49 | v2.1 December 2014 50 | *Change initialization method and added convenience methods on StateMachineBehaviour. NotePrevious projects will need change Initialization calls. 51 | 52 | v2.0 November 2014 53 | Complete rewrite of State Machine for Unity. Now has the following features 54 | 55 | * Simple use of Enums as state definition. 56 | * Minimal initialization - one line of code. 57 | * Incredibly easy to add/remove states 58 | * Uses reflection to avoid boiler plate code - only write the methods you actually need. 59 | * Compatible with Coroutines. 60 | * Tested on iOS and Android 61 | 62 | v1.0 April 2012 63 | A state machine for Unity --------------------------------------------------------------------------------