【Unity】PlayMaker完全に理解する (1)

(注意)タイトルと本編は一切関係ありません

今回の目標

「PlayMakerを用いて以下の処理を行う」

using UnityEngine;

public class PlayerMovement : MonoBehaviour {
    private void Update() {
        if (Input.GetKey(KeyCode.W)) {
            transform.position += transform.forward;
        } else if (Input.GetKey(KeyCode.S)) {
            transform.position -= transform.forward;
        }
    }
}

目標のプログラムの分解

目標のプログラムを分解すると以下のようになります

using UnityEngine;

public class PlayerMovement : MonoBehaviour {
    private Vector3 currentPosition;
    private Vector3 moveDirection;
    private bool isW;
    private bool isS;

    private void Update() {
        isW = Input.GetKey(KeyCode.W);
        isS = Input.GetKey(KeyCode.S);

        if (isW) {
            currentPosition = transform.position; // get position
            moveDirection = transform.forward;    // set move direction
            currentPosition += moveDirection;     // set next position
            transform.position = currentPosition; // update position
        } else if (isS) {
            currentPosition = transform.position; // get position
            moveDirection = transform.forward;    // set move direction
            currentPosition -= moveDirection;     // set next position
            transform.position = currentPosition; // update position
        }
    }
}

PlayMakerで実装する

(1) PlayerオブジェクトPlayerMovement というFSMを追加👇

f:id:atas10703:20190526033216p:plain

(2) 分解したプログラムを参考に変数を追加👇

f:id:atas10703:20190526034007p:plain

(3) Input MoveForward MoveBack の3つの状態を作成👇

f:id:atas10703:20190526034440p:plain

(4) InputW InputS ToInput というイベントを追加👇

f:id:atas10703:20190526035700p:plain

(5) 状態Input に InputW InputS の遷移を追加し、4つのアクションを設定👇

f:id:atas10703:20190526035307p:plain

Get Key Keyを押している間 true、その結果をStore Resultに格納

Bool Changed Bool Variable の値が変化した時、Change Event の状態に遷移

(6) 状態MoveForward に ToInput の遷移を追加し、2つのアクションを設定👇

f:id:atas10703:20190526040216p:plain

(7) ゲームシーンを再生し、Wキーを押すと状態が遷移するのを確認👇

f:id:atas10703:20190526040744p:plain

(8) 標準では transform.forward transform.up transform.right が無いっぽい?ので

Assets/PlayMaker/Actions/Transform に GetDirectionVector.cs を追加👇

// 参考 https://hutonggames.com/playmakerforum/index.php?topic=41.0

using UnityEngine;

namespace HutongGames.PlayMaker {
    [ActionCategory(ActionCategory.Transform)]
    [Tooltip("Get the Direction (Forward, Up, Right) Vector of the Transform")]
    public class GetDirectionVector : FsmStateAction {
        public enum Direction {
            Forward,
            Up,
            Right
        }
        public Direction direction;
        
        [RequiredField] public FsmOwnerDefault gameObject;
        [UIHint(UIHint.Variable)] public FsmVector3 vector;
        [UIHint(UIHint.Variable)] public FsmFloat x;
        [UIHint(UIHint.Variable)] public FsmFloat y;
        [UIHint(UIHint.Variable)] public FsmFloat z;
        public bool everyFrame;

        public override void Reset() {
            gameObject = null;
            vector = null;
            x = null;
            y = null;
            z = null;
            direction = Direction.Forward;
            everyFrame = false;
        }

        public override void OnEnter() {
            DoGetForward();

            if (!everyFrame) Finish();
        }

        public override void OnUpdate() {
            DoGetForward();
        }

        private void DoGetForward() {
            var go = Fsm.GetOwnerDefaultTarget(gameObject);

            if (go == null) return;

            var directionVector = Vector3.zero;

            switch (direction) {
                case Direction.Forward:
                    directionVector = go.transform.forward;
                    break;
                case Direction.Up:
                    directionVector = go.transform.up;
                    break;
                case Direction.Right:
                    directionVector = go.transform.right;
                    break;
            }

            if (directionVector == Vector3.zero) return;

            vector.Value = directionVector;
            x.Value = directionVector.x;
            y.Value = directionVector.y;
            z.Value = directionVector.z;
        }
    }
}

(9) 状態MoveForward に4つのアクションを設定👇

f:id:atas10703:20190526042023p:plain

Get Position GameObject の Space 座標を Vector に格納

Get Direction Vector GameObject の Direction(Right、Up、Forward)をVectorに格納

Vector3 Add Vector Variable に Add Vector を加算

Set Position GameObject の Space 座標に Vector に代入

Wキーを押している間は前方に移動します(やった!)

(10) 状態MoveBack にも状態MoveForward と同様に設定👇

f:id:atas10703:20190526043819p:plain

Vector3 Subtract Vector Variable から Subtract Vector を減算

(閉じているアクションは状態MoveForwardと同じです)

これにて完成!!!

もう少し簡単に実装する

Get Key に拘らなければもう少し簡単に実装することができます

(1) 状態Input のアクションを修正👇

f:id:atas10703:20190526044825p:plain

Get Key Down Key を押した時、Send Event の状態に遷移

(2) 状態MoveForward のアクションを修正👇

f:id:atas10703:20190526045117p:plain

Get Key Up Key を離した時、SendEventの状態に遷移

(3) 状態MoveBack も同様に修正👇

f:id:atas10703:20190526045147p:plain

この修正により、bool型の変数 isW isS が不要になります

完全に理解するまでにはまだまだ時間がかかりそうですが、引き続きガンバリマス!!!

前回👇 atas10703.hatenablog.com