【Unity】VisualScriptingチュートリアル3

toshizabeth.hatenablog.com

第三回

概要

先日、Unity公式のYoutubeチャンネルで素晴らしい動画が上がっていました

www.youtube.com

今回はこちらの動画を参考に、少しシンプルにしたものを手元で再現してみようと思います

実装

キューブとカプセルが配置されている世界で、キューブを手動で動かしカプセルに衝突したときに

カプセルの上に配置されたオブジェクトがアクティブ化。
衝突から離れたときに非アクティブ化。
を実現していきます


1. GameObjectの準備

Sceneに以下のオブジェクトを配置します

  • Cube : 動かす対象
  • Capsule : 衝突先のオブジェクト
  • Caution : カプセルの頭上に配置されたオブジェクト。衝突されたらアクティブ化される

f:id:toshizabeth:20210919192320p:plain

Cautionは最初非アクティブにしておきます


衝突判定に必要なため、

  • Cubeには BoxCollider と Rigidbody (UseGravityはOff)。そして判定に必要なため Player というタグを付ける
  • CapsuleにはCapsuleCollider (IsTriggerがON)

を付けておいてください


2. Cubeを動かせるようにする

キーボードの十字キーでCubeオブジェクトを前後左右動かします

   public class CubeController : MonoBehaviour
    {
        void Update()
        {
            if (Input.GetKey (KeyCode.UpArrow)) 
            {
                transform.Translate(0.0f, 0.0f, 0.1f);
            }
            
            if (Input.GetKey (KeyCode.DownArrow)) 
            {
                transform.Translate(0.0f, 0.0f, -0.1f);
            }
            

            if (Input.GetKey (KeyCode.LeftArrow)) 
            {
                transform.Translate(-0.1f, 0.0f, 0.0f);
            }
            
            if (Input.GetKey (KeyCode.RightArrow)) 
            {
                transform.Translate(0.1f, 0.0f, 0.0f);
            }
        }
    }
}

このような適当なクラスを作成してCubeに貼り付けちゃいましょう

f:id:toshizabeth:20210919192659g:plain



3. Capsuleに衝突したことを検知するGraphを構築する

Capsule に AddComponent から 「StateMachine」を付けます
New ボタンから適当にアセットを保存し、Edit Graph ボタンで編集に入ります

何もない場所で
右クリック > Create Script State を押して「接触状態の時の動き」を配置するユニットを作成します


f:id:toshizabeth:20210919193354p:plain

左上のタイトルを編集し

という名前をつけました。

接触状態と非接触状態が交互に切り替わるため、お互い Make Transition で相互につなげます

f:id:toshizabeth:20210919220749p:plain

接触状態 → 接触状態 の遷移条件

接触状態から接触状態になるためには「キューブがカプセルに接触した」つまり OnTriggerEnter が呼び出さればいいわけで
そのような状態を「非接触状態→接触状態」の条件に記載します (黄色の部分をダブルクリック)

  1. OnTriggerEnterユニットを置く
  2. if ユニットを置いて true と Triggeer Transition をつなげる

上記のみでは「Cube以外にあたったときも反応してしまう」ので、CompareTag を取り付けます。
これは Tag に記載したオブジェクトのみ反応してくれるユニットです。

今回はCubeにはPlayerというタグを付けました。
なので Compare Tag には Player というタグで反応してもらうようにします

f:id:toshizabeth:20210919220936p:plain

接触状態 → 非接触状態の遷移条件

先ほどとほぼ一緒ですが、 OnTriggerEnter ユニットではなく OnTriggerExit ユニットを取り付けます。
これで 「カプセルからキューブが離れたときに反応する」ようにします

f:id:toshizabeth:20210919221412p:plain


これでキューブからカプセルに接触したときに 接触状態の Script State に遷移するようになりました!

f:id:toshizabeth:20210919221823g:plain

接触状態のScriptStateにSetAcriveの処理を書く

これでオブジェクト同士の当たり判定で赤丸の接続状態に遷移するようになりました。

f:id:toshizabeth:20210919221954p:plain

次は
「 Caution : カプセルの頭上に配置されたオブジェクト。衝突されたらアクティブ化される」
を ScriptStateに記述していきたいと思います

赤丸の接続状態をダブルクリックして...
中に
接触中はCautionをアクティブに。非接触中はCautionを非アクティブに」
するユニットを配置していきます

その前に
Cautionオブジェクトのアクティブを切り替えるためには、Cautionオブジェクトを知っておく必要があります

カプセルオブジェクトにStateGraphを追加した時、合わせてVariablesというコンポーネントも追加されています。
簡単に説明すると、ここにオブジェクトを登録するとカプセルのStateMachineで参照できるようになる
ということです。

なので Variables に CautionCube という名前で Cautionオブジェクトをアタッチします

f:id:toshizabeth:20210919222543p:plain


これでStateMachine内でCautionオブジェクトのアクティブが切り替えられるようになりました
そして次の通りにユニットを配置します

  1. 接触状態になった時を知るためにOnEnterStateユニットを配置
  2. 接触状態になった時を知るためにOnExitStateユニットを配置
  3. それぞれ、SetActiveユニットを配置して、 Value に チェックあり、チェックなし版をつなげる
  4. GetVariableユニットを配置して、今回は「Object」からCautionCubeを選択してそれぞれ SetActive ユニットにつなぎ合わせる

f:id:toshizabeth:20210919222820p:plain


これで 接触、非接触状態になったときにSetActiveが切り替えられるようになりました。
GetVariable はその名の通り変数、オブジェクトを取得するユニットです。
Variableで登録したオブジェクトがここで参照できるようになります。

今回はカプセルのVariableコンポーネントにCautionを登録したため、Objectから選択するようになっています
(スコープ範囲による。今はスルー)


これで実行すると、キューブがカプセルに衝突すると、カプセルの頭上のCautionオブジェクトが表示されるようになります

f:id:toshizabeth:20210919223308g:plain


以上!