こんにちは。ヤマヤタケシです。
プログラミングやってます。
ステートマシンというちょっと大げさな言葉があります。
FSMと略したりします。
日本語で言うと「状態機械」です。
ステートマシンをうまく使うと色々すっきり書けます。
ステートマシンを使わない場合は、フラグをつかう事になります。
とか、昔もこのブログで書いたことあるきがしてきました。
まあ、Unityをつかうようになってもステートマシンは手放せないんです。
オレオレステートマシンというのは、1ステート=3メソッドと、Update, Changeで作られています。
状態を変化させると、終了、初期化、が呼ばれます。
中途半端な隙がありません。
まあ、大したコードではない割に便利なので、ここに公開します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
// // // StateMachien for Unity // using System; using System.Collections.Generic; using UnityEngine; public class StateMachine<T> { class State { public State(T tag, Action init, Action exit, Action update) { this.Tag = tag; this.Init = init; this.Exit = exit; this.Update = update; } public T Tag; public Action Init; public Action Exit; public Action Update; } Dictionary<T,State> stateList; State now; public StateMachine() { stateList = new Dictionary<T,State>(); } public void Add( T tag, Action init, Action exit, Action update ) { stateList.Add(tag, new State( tag : tag, init : init, exit : exit, update: update) ); } public void Change(T tag) { if( now != null) { if( now.Exit != null ) { now.Exit(); } now = null; } now = stateList[tag]; if( now != null) { if (now.Init != null) { now.Init(); } } } public void Update() { if( now == null) { return; } if( now.Update != null ) { now.Update(); } } } |
クラスAはWait状態とLaser状態があります。
ステートマシンに登録して、切り替えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
// class A { enum StateTag { Wait, Laser, } StateMachine<StateTag> state; void Start () { StateMachine<StateTag> state = new StateMachine<StateTag>(); { state.Add( StateTag.Wait, WaitInit, WaitExit, WaitUpdate ); state.Add( StateTag.Laser, LaserInit, LaserExit, LaserUpdate ); } state.Change(StateTag.Wait); } void Update () { state.Update(); } // Wait void WaitInit(){} void WaitExit(){} void WaitUpdate() { if( Input.GetMouseButton(0)) { state.Change(StateTag.Laser); } } // Laser void LaserInit() { } void LaserExit(){} void LaserUpdate() { if( Input.GetMouseButton(0)) { } else { //終了 state.Change(StateTag.Wait); } } } |
そんじゃまた。