もくじ
サンプルプロジェクトではPlayerの回転処理やEnemyの移動処理をC#スクリプトでコーディングしました。ものすごくシンプルなコードなんですが、せっかくなのでUnity 2022に標準搭載されているVisual Scriptingを使って処理を実装しなおします。
作成したC#スクリプトはPlayer、Enemy、Spawnerの3種類です。各スクリプトを参考に3つのVisual Scripting Graphを作成してグラフを作成します。
誤動作を避けるために先に3つのゲームオブジェクトにアタッチされているScriptコンポーネントを削除しておきます。
Player Script Graph
ProjectウィンドウでAssets配下にVisualScriptsフォルダを作成します。VisualScriptsフォルダを表示させウィンドウ内を右クリックしコンテキストメニューから「Create > Visual Scripting > Script Graph」を選択しScript Graph Assetを作成します。名前をPlayerとします。( 4.1)
Hierarchyウィンドウ内のリストからPlayerゲームオブジェクトを選択しInspectorの「Add Component」ボタンをクリックしScript Machineコンポーネントを追加します。Graphパラメータボックスを選択し、先ほど作成したPlayerスクリプトグラフを設定します。( 4.2)
Projectウィンドウ上のPlayerスクリプトグラフをダブルクリックするか、もしくはInspectorの「Edit Graph」ボタンをクリックし、Script Graphウィンドウを開きます。初回の起動時にはVisual Scriptingの初期化処理が走り、完了すると空のScript Graphウィンドウが表示されます。( 4.3)
C#スクリプトを参考にノードを追加していきます。最初にPlayerの回転処理を追加します。PlayerクラスのUpdate関数内の以下の処理を追加します。( 4.4)
transform.Rotate(Vector3.forward * turnSpeed * Input.GetAxisRaw("Horizontal") * Time.deltaTime);
詳細は割愛しますが、Player Script Graphウィンドウ内に必要なノードを配置してグラフを組むと左右のカーソルキーでPlayerの回転が可能なグラフが作成できます。Visual Scriptingの基本的な使い方は過去の記事を見て頂ければ分かると思います。( 4.5)
Enemy Script Graph
Enemyの移動処理を作成します。先ほどと同様にEnemyスクリプトグラフを作成します。EnemyのPrefabを一時的にSceneに作成しておいてScript Machineコンポーネントを追加し、Enemyスクリプトグラフをアタッチします。Script Graphウィンドウを開いて、Playerに向かって移動する処理に必要なノードを追加しグラフを作成します。( 4.6)
transform.position = Vector2.MoveTowards(transform.position, player.transform.position, speed * Time.deltaTime);
注意点ですが、Prefabからゲームオブジェクトを参照する場合、Scene変数にしておかないとうまく動きませんでした。Player参照用の変数はScene変数にしておく必要があります。
Spawner Script Graph
3つ目のスクリプトグラフとしてSpawner Script Graphを作成し、Spawn処理を追加します。( 4.7)
一定間隔でEnemyを任意の位置から生成させる処理を作ります。まず必要な変数を定義しますが、配列についてはVisual Scriptingでも使えるList変数を使うことにします。( 4.8)
ひとまずテストのためマウスクリックでEnemyを生成するノードグラフを作成してみました。C#スクリプトだと3行程度で済むコードでもVisual Scriptingで組むとちょっと複雑になってしまいます。これで問題ないようなので、一定間隔で自動生成できるように条件分岐を追加していきます。( 4.9)
サンプルプロジェクトのコードと同様の処理を追加します。timeBetweenSpawnsに設定した時間が経過する度にEnemyを自動生成するグラフを作成しました。( 4.10)
PlayerとEnemyの衝突処理
EnemyのScript GraphにPlayerとEnemyの衝突処理を追加します。以下のC#スクリプトのコードをグラフ化します。( 4.11)
void OnTriggerEnter2D(Collider2D other)
{
if (inactive == false)
{
if (other.tag == "Hole")
{
Destroy(gameObject);
}
if (other.tag == "Player" || other.tag == "Enemy")
{
speed = 0;
transform.parent = player.transform;
}
inactive = true;
}
}
ダメージ処理
続けてダメージ処理とスコアの計算処理を追加します。Playerスクリプトグラフにカスタムイベント処理を記載して、Enemyの衝突イベントで呼び出す形になります。
public void TakeDamege()
{
health--;
healthDisplay.text = "Health: " + health;
if (health <= 0)
{
SceneManager.LoadScene("Game");
}
}
Playerスクリプトグラフにカスタムイベント処理を記述してダメージ処理を追加し、体力がゼロになった時にシーンのリセット処理を行います。( 4.12)
EnemyスクリプトグラフのCollision処理の後にカスタムイベントを呼び出しするTriggerノードを追加します。Playerスクリプトグラフに追加したTakeDamageイベントを呼び出します。( 4.13)
スコア計算処理
PlayerがうまくEnemyをキャッチできた場合にスコアアップさせる計算を入れます。以下のコード処理をグラフで作成します。( 4.14)
public void AddScore()
{
score++;
scoreDisplay.text = "Score: " + score;
}
以上でC#スクリプトの処理をすべてVisual Scriptingに移し替えることができたと思います。
如何でしょうか。多少なりともC#スクリプトのプログラミングに慣れている場合、Visual Scriptingの冗長的な書き方が面倒になってきませんか。僕個人的にはC#スクリプトで書いた方が楽だとは思っていますが、Visual Scriptingはブロック感覚で組めるので遊びの感覚に近いかもしれません。
Enemy回転処理
サンプルプロジェクトにはない処理ですが、Enemyに回転処理を追加します。回転速度と方向の変数をそれぞれturnSpeedとdirectionという新たな変数として追加しています。スタート時の回転方向のランダム処理は、もっと効率的な方法があると思うのですが、今はこれしか思いつきませんでした。( 4.15)
EnemyスクリプトグラフのUpdate処理のなかで回転を追加します。( 4.16)