UnityのVisual Scriptingを使ってキャラクター移動スクリプトの作成

記事内に広告が含まれています。

前の記事でVisual Scriptingの使い方についてみていきました。

UnityのVisual Scriptingの使い方
UnityのVisual Scriptingを使うと視覚的にゲームのスクリプトを作成することが出来ます。今回はVisual Scriptingの使い方を学び、簡単なサンプルを作ってみます。

今回はより実践的にキャラクター移動スクリプトをVisual Scriptingを使って作成していきたいと思います。

C#スクリプトを使ったキャラクター移動スクリプトは何度も作成しているので、C#スクリプトで作ったものをVisual Scriptingで同じように作ってみるという感じです。

キャラクターのAnimatorコンポーネントに取り付けるAnimatorControllerは既に作成してあり、Float型のSpeedというアニメーションパラメータの作成をし、Idle状態、Walk状態を作り、

Idle→WalkはSpeedが0.1以上
Walk→IdleはSpeedが0.1以下

の時に遷移するようにしておきます。

ここら辺は以下の記事を参照してください。

Unityのアニメーションの切り替えシステムとスクリプト
Unityのアニメーションの切り替えシステムであるAnimatorControllerの設定とスクリプトからアニメーションを制御していきます。
スポンサーリンク

Visual Scriptingでキャラクター移動スクリプトを作成する

Visual Scriptingでキャラクター移動スクリプトを作成する前に、C#スクリプトで動くキャラクターを作って比較する事にします。

C#スクリプトキャラクターとVisual Scriptingキャラクターの作成

キャラクターモデルにはスタンダードアセットのEthanを使用し、Animatorコンポーネントには作成したAnimatorControllerを設定し、CharacterControllerコンポーネントを取り付けてコライダのサイズを調整しておきます。

また新しくCharacterScriptという名前のC#スクリプトを作成し、これも取り付けます。

Ethanのインスペクタは以下のようになります。

VisualScriptingで動かすキャラクターサンプルの見本のEthan

シーンには地面となるPlane等のゲームオブジェクトを設置し、キャラクターを移動出来る事を確認してください。

問題なく動くようであればEthanゲームオブジェクトを選択し、Ctrl+Dキーを押して複製し、インスペクタのCharacterScriptコンポーネントを削除します。

さらに、Add ComponentからScript Machineコンポーネントを取り付けます。

Assetsフォルダで右クリックからVisual Scripting→Script Graphを選択し、名前をCharacterScriptとし、Script MachineコンポーネントのGraphにドラッグ&ドロップして設定します。

Visual Scriptingで動くキャラクターの設定

CharacterScriptグラフの中身を作成する

キャラクターの設定が出来たので、C#スクリプトで行った処理をVisual Scriptingに置き換えて作成していきます。

C#スクリプトではcharacterController、animator、velocity、moveSpeedフィールドを使用しています。

characterController、animator、velocityはグラフ変数、moveSpeedはオブジェクト変数として定義することにします。

ヒエラルキーのEthan(1)ゲームオブジェクトを選択し、CharacterScriptスクリプトグラフウインドウで変数を設定します。

VisualScriptingキャラクターのスクリプトで使うグラフ変数

VisualScriptingキャラクターのスクリプトで使うオブジェクト変数

characterControllerとanimatorは自身のゲームオブジェクトから取得するのでスクリプトグラフでStartユニットを作成し、そこからポートを繋いでグラフ変数にそれぞれ設定します。

Startユニットからフローを繋げてグラフ変数を設定する

次にUpdateユニットを作成し、そこからキャラクターの移動処理やアニメーターの操作処理を追加していきます。

VisualScriptingで作ったキャラクターが接地しているかどうかの部分

Updateユニットからifユニットにフローを繋ぎ、グラフ変数のcharacterControllerを取得してプロパティのisGroundedをチェックしてそれがTrueだった時は次のユニットに移動します。

Falseだった時は重力の計算をし、移動処理をする部分に行きますが、とりあえず置いておきます。

Trueだった時は以下のようなユニットを作成します。

VisualScriptingのキャラクター移動スクリプトの移動値の計算

Set Variableでグラフ変数のvelocityにGet Zeroユニットを接続し、接地した時は移動速度のXYZを全て0にします。

その後Input ManagerのHorizontalとVerticalの値を取得し、新しいVector3の値を作ります。

VisualScriptingのキャラクター移動スクリプトのアニメーション切り替え処理

新しく作ったVector3の値のMagnitude(ベクトルの長さ)を取得し、それが0より大きい(移動の入力がされている)時はアニメーターのSpeedアニメーションパラメーターに入力値のMagnitudeを設定します。

入力値が0以下の場合はアニメーションパラメーターのSpeedに0を設定します。

次はキャラクターの移動値が0より大きかった時の処理です。

VisualScriptingのキャラクター移動スクリプトで入力した方向にキャラクターを向ける処理

キャラクターの現在の位置に入力した方向(単位ベクトル)を足した向きにLookAtを使ってキャラクターを向けています。

キャラクターの向きを変更したら、キャラクターの向いている向きに移動スピードを掛けて速度を計算します。

VisualScriptingのキャラクター移動スクリプトでキャラクターの速度を計算する処理

Get Forwardユニットでキャラクターの向きを取得し、それにオブジェクト変数のmoveSpeedをかけ、それをvelocityに代入しています。

次はC#スクリプトで接地かどうかを判断しているif文の後の重力とCharacterControllerのMoveメソッドを使った実際の移動処理の部分を作成します。

まずは重力の計算処理を作ります。

VisualScriptingのキャラクター移動スクリプトの重力の計算処理

Get Gravityユニットで重力値を取得したものとGet Delta Timeをかけて1フレームの重力での移動値を計算し、グラフ変数のvelocityと足します。

それを再度velocityに入れています。

重力の計算をしてvelocityに値を設定するSet VariableユニットにはcharacterControllerのisGroundedがTrueであれ、Falseであれ必ず計算する必要があります。

なので「接地しているかどうか」グループにあるifユニットと「移動速度計算」グループのSet Variableユニット(velocityの値を設定しているやつ)の両方のフローポートからフローを繋ぐ必要があります。

最後にCharacterControllerのMoveメソッドで実際の移動処理をする部分を作成します。

VisualScriptingのキャラクター移動スクリプトで実際に移動させる処理の部分

ここではvelocityにGet Delta Timeユニットをかけた値をCharacterControllerのMoveユニットに接続しています。

全体のユニットと接続は以下のようになります。

CharacterScriptスクリプトグラフの全体像

これで機能が出来ました。

Unityを実行してC#スクリプトのキャラクターと動きが変わらないか確認してください。

ステートグラフを使ってドアを開く機能を作成する

Visual Scriptingを使ってキャラクター移動の機能が出来ました。

次はドアを作成して、キャラクターが近づいたらドアを開く、離れたらドアを閉じるというような機能を作成してみます。

ドアの状態に合わせて処理を変更したいので、ステートグラフを使います。

ドアのゲームオブジェクトの作成

ドアのゲームオブジェクトはCubeを使って作成しますが、ドアの開閉のアニメーションはドアの親の位置を基点に回転させ作ります。

まずはヒエラルキーにCubeを作成し、名前をDoorObjとし、インスペクタのTransformで以下のように設定します。

DoorObjのインスペクタのTransform

次にヒエラルキーに空のゲームオブジェクト(Create Empty)を作成し、名前をDoorBaseとし、DoorObjの回転の基点となる位置に移動させます。

DoorBaseの位置

インスペクタで見ると以下のような感じです。

DoorBaseのインスペクタ

さらに空のゲームオブジェクトを作成し、名前をDoorとします。

次にDoorObjをDoorBaseの子要素に移動させます。

次にDoorBaseをDoorの子要素に移動させます。

ヒエラルキーは以下のようになりました。

ドアの階層

さらにDoorゲームオブジェクトのインスペクタのTransformを変更します。

Doorのインスペクタ

Doorにはキャラクターが侵入したかどうかを判定するコライダを取り付けます。

Doorゲームオブジェクトにキャラクターを検知する範囲を作成する

範囲として使用するのでSphere ColliderのIs Triggerにチェックを入れます。

床ゲームオブジェクトの作成

さらにヒエラルキーにPlaneを作成し、インスペクタで以下のように設定します。

VisualScriptingのドアのサンプルでの床のゲームオブジェクトのインスペクタ

床とドアは以下のようになりました。

VisualScriptingのドアのサンプルでのゲームビュー

ドアの開閉アニメーションの作成

ドアの開閉アニメーションを作成します。

UnityメニューのWindowからAnimation→Animationを選択し、アニメーションウインドウを開きます。

ヒエラルキーのDoorBaseゲームオブジェクトを選択し、AnimationウインドウのCreateを押して、新しく出てきたウインドウでCloseという名前で保存します。

そのままAnimationウインドウのCloseの部分を押し、Create New Clipを選択し、Openという名前で保存します。

Animationウインドウの録画ボタンを押して、ヒエラルキーのDoorBaseを選択し、シーンビューでY軸を回転させます。

0:00の部分ではDoorBaseのTransformのRotationのYを0、1:00の部分ではDoorBaseのTransformのRotationのYを-130となるようにキーフレームを打ちます。

AssetsフォルダにあるOpenアニメーションクリップを選択し、インスペクタのLoop Timeのチェックを外してループ再生しないようにします。

Animationウインドウでのアニメーションの作成については、以下の記事を参照して作成してみてください。

Unityで家の扉の開閉が出来るようにする
Unityのゲームで家の扉の開閉が出来るようにする機能を作成していきます。

DoorBaseアニメーターコントローラーでBool型のOpenedというアニメーションパラメーターを作成し、

Close状態とOpen状態を作ります。

それぞれ作成したアニメーションクリップを設定します。

また、

Close→OpenへはOpenedがtrueの時
Open→CloseへはOpenedがfalseの時

に遷移するようにします。

これでドアのアニメーションが出来ました。

ドア用のステートグラフを作成する

ドア用のステートグラフを作成し、ドアの状態によって処理を分けるようにします。

Assetsフォルダ内で右クリックからVisual Scripting→State Graphを選択し、名前をDoorScriptとします。

DoorScriptステートグラフを開いて、右クリックからCreate Script Stateを選択します。

最初に作成したユニットがデフォルトの状態になります。

他の状態ユニットをスタートにしたい時はユニットを選択し、右クリックからToggle Startを選択して切り替えます(スタート状態はユニットの上部が緑色になります)。

Startユニットを選択し、Graph Inspectorで名前をCloseに変更します。

State Scriptの名前を変更する

名前を変更したらCloseユニットをダブルクリックし、中身を記述していきます。

元からある他のイベントユニットは使わないので削除しておきます。

ドアのステートグラフのClose状態のユニット

On Trigger Enterユニットで他のコライダが侵入した時にCompare Tagを使ってPlayerタグが設定されたゲームオブジェクトかどうかを判断します。

Trueの時はAnimatorのSet Boolユニットを使って自身のゲームオブジェクトの子(DoorBase)のAnimatorのOpenedをTrueにします。

その後、Custom Event Triggerユニットに接続しDoorOpenというカスタムイベントを発生させます。

ここまで出来たら親のDoorScriptの編集に戻ります。

Close状態を選択し、右クリックからMake Transitionを選択した後にマウスの左ボタンを押して確定し、新しい状態への遷移を作成します。

遷移条件部分をダブルクリックし、遷移条件を設定します。

Closeからの遷移条件を作成する

Close状態の中でDoorOpenというイベントを発生させたので、このイベントが発生したら遷移するようにします。

Close状態からの遷移条件はDoorOpenイベントが発生したら

DoorScriptステートグラフに戻ります。

先ほど作成した新しい状態を選択し、Graph Inspectorで名前をOpenに変更します。

新しい状態をOpen状態に変更する

Close状態のユニットをCtrl+Aキーで全て選択した後、Ctrl+Cキーを押してコピーし、Open状態の中に貼り付けます。

ドアのステートグラフのOpen状態のユニット群

元からある他のイベントは使わないので削除します。

最初のOn Trigger EnterだったイベントをOn Trigger Exitに変更します。

またAnimatorのSet BoolでOpenedのチェックを外すようにし、カスタムイベントはDoorCloseに変更します。

DoorScriptステートグラフに戻り、Open状態を選択し、右クリックからMake Transitionを選択し、Close状態を押します。

OpenからCloseへの遷移条件をダブルクリックし、中身を以下のようにします。

OpenからCloseへの遷移条件のユニット

カスタムイベントのDoorCloseを受け取ったらOpenからCloseへと遷移するようにします。

DoorにState Machineを取り付けDoorScriptを設定する

DoorScriptが出来たので、ヒエラルキーでDoorゲームオブジェクトを選択し、インスペクタのAdd ComponentからVisual Scripting→State Machineを選択して取り付け、GraphにDoorScriptを設定します。

DoorにState Machineの取り付けとDoorScriptの取り付け

実行して確認する

機能が出来たので確認をしますが、その前にキャラクターにはPlayerタグを設定しておきます。

キャラクターにはPlayerタグを設定する

キャラクターを移動させドアに近づくとドアが開き、離れるとドアが閉まります。

上のようになりました。

終わりに

Visual ScriptingのScript Graphで作成すると慣れていないせいかフローポートをどう繋げばいいかわからなくなりますね。(^_^;)

タイトルとURLをコピーしました