【Unity】xNode入門①|xNodeとは?導入からNode・Graphの基本まで
Unityでゲームを作っていると、処理やデータの関係がだんだん複雑になってくることがあります。
たとえば、会話システムを作る場合、
「この会話の次はこの会話へ進む」
「この条件を満たしていたらAへ進む」
「満たしていなければBへ進む」
といった分岐が増えていきます。
C#スクリプトだけで作ることはできますが、処理の流れが複雑になると、コードを見て全体の関係を把握するのが難しくなってきます。
そこで利用できるものの1つが、今回紹介する xNode です。
xNodeを使うと、Unity Editor上にNodeを配置し、それぞれを線でつないでデータや処理の関係を管理できます。
今回はxNode入門の第1回として、
・xNodeとは何か
・xNodeの導入
・Graphの作成
・Nodeの作成
・InputとOutput
・Node同士の接続
について確認していきます。
今回のゴールは「自分で作ったNodeをGraph上に配置して、Node同士を線でつなぐ」ところまでです。
値の受け渡しや計算については、次回詳しく確認します。
1.xNodeとは?
xNodeは、Unityでノードベースのシステムを作るためのオープンソースのフレームワークです。
たとえば、次のようなシステムを作るときに利用できます。
・会話システム
・イベント進行
・クエスト管理
・スキルツリー
・条件分岐
などです。
xNodeでは、情報や処理を1つの「Node」として作り、それぞれのNodeを線で接続できます。
C#のコードだけでは分かりにくかった関係を、Unity Editor上で視覚的に確認できるようになります。
xNodeは何をしてくれるのか?
ここで最初に理解しておきたいポイントがあります。
xNodeをインストールしただけで、「会話システム」や「AIシステム」が完成するわけではありません。
xNodeは、あくまで「自分でノードシステムを作るための土台」です。
たとえば、
Start
↓
Talk
↓
BattleというNodeを作ったとしても、Start Nodeを実行したら自動的にTalkが実行され、その次にBattleが実行される、という機能までxNodeが自動で作ってくれるわけではありません。
Nodeの情報をどのように読み取ってゲームを動かすかは、自分でC#を使って作らなければなりません。
Unity Visual Scripting との違い
Nodeと聞くと、UnityのVisual Scriptingを思い浮かべる方もいるかもしれません。
見た目は似ていますが、目的は少し違います。
Unity Visual Scriptingでは、
Start
↓
移動
↓
ジャンプ
↓
攻撃のように、Nodeを接続してゲームの処理そのものを作ることができます。
一方、xNodeは、Nodeや接続関係を作るためのフレームワークです。
たとえば、
会話1
↓
会話2
↓
選択肢というデータをxNodeで作り、そのデータをC#スクリプトから読み取ってゲームを進行させる、といった使い方ができます。

大まかなイメージとしては、
Unity Visual Scripting :Nodeをつなぐ → ゲームの処理を作る
に対して、
xNode:Nodeをつなぐ → データや関係を作る → C#から読み取って利用する
もちろん、実装方法によってはxNodeで処理フローを作ることもできます。ただし、「Nodeを置けば自動的にゲームが動くツールではない」ということは覚えておきましょう。
2.xNodeを構成する基本要素
xNodeを理解するときは、まず次の4つを覚えておくと分かりやすいです。
・Graph
・Node
・Port
・Connection

順番に確認してみます。
Graph
Graphは、複数のNodeをまとめて管理するものです。
たとえば会話システムなら、
会話Graph
├ 会話Node
├ 会話Node
├ 選択肢Node
└ 終了Nodeというイメージです。
xNodeのGraphは NodeGraph クラスを継承して作ります。
GraphとNodeはいずれもScriptableObjectをベースとしており、Project内のアセットとして保存できます。
Node
Nodeは、Graphの中に配置する1つ1つの箱です。
たとえば、

や、

といったものです。
Nodeは、Nodeクラスを継承して作ります。
Port
Portは、Node同士をつなぐための接続口です。
たとえば、以下のような形です。

入力側を Input Port、出力側を Output Port と呼びます。
Connection
PortとPortをつないでいる線がConnectionです。
Output ○──────────○ Inputこの接続情報を利用することで、
「このNodeはどのNodeとつながっているのか」
を取得できます。
3.xNodeの作成
3-1.xNodeをUnityに導入する
それではxNodeをUnityへ追加してみましょう。
今回は Package Managerを使います。
xNodeの公式GitHubでは、Git URLを利用した Package Managerからのインストール方法が案内されています。
Window → Package Manager → Package Manager

Package Manager左上の「+」をクリックし、
Install package from git URL... を選択します。
Git URLには、次を入力します。
https://github.com/Siccity/xNode.git
追加すると、プロジェクトへxNodeがインストールされます。
以下のエラーが出たときは、Gitがインストールされていない可能性があります。
ご利用のパソコンに Git をインストールしてみましょう。

この方法を使用する場合は、パソコンにGitがインストールされ、PATHから利用できる必要があります。
公式には、OpenUPMやソースファイルをAssetsへ配置する方法なども案内されています。
3-2.Graphの作成
xNodeを導入したら、Graphを作ります。
今回は「SampleGraph」という名前で作ってみます。
C#スクリプトを作成し、名前を SampleGraph に指定、次のように記述します。
using UnityEngine;
using XNode;
[CreateAssetMenu]
public class SampleGraph : NodeGraph
{
}コードの解説
public class SampleGraph : NodeGraph通常のUnityスクリプトでは、MonoBehaviour を継承することが多いですが、今回は NodeGraph を継承しています。
これによって、このクラスを xNode の Graph として利用できるようになります。
[CreateAssetMenu]これを付けることで、 Projectウィンドウで右クリックし、Create → Sample Graph からGraphアセットを作成できるようになります。
3-3.SampleGraphを作成する
スクリプトのコンパイルが終わったら、Projectウィンドウで右クリックします。
Create → SampleGraph であらたなSampleGraphを作成します。

SampleGraphを作成すると、
New SampleGraph.assetというアセットができます。
これが今回作るNodeをまとめるGraphです。
名前は new を消して「SampleGraph」にしておきます。
Graphアセットをダブルクリックしてみましょう。
xNodeのGraph Editorが開きます。

最初は何もNodeがないので、何も配置されていない空の画面になります。
ここに自分で作ったNodeを追加していきます。
3-4.最初のNodeを作ってみる
続いてNodeを作ります。
今回は「NumberNode」という非常に簡単なNodeを作ります。
スクリプトファイル:NumberNode.csを作成して、次のように記述します。
using XNode;
public class NumberNode : Node
{
public int value = 10;
}コードの解説
public class NumberNode : Node今度は「Node」を継承しています。
これによって、このクラスを xNode の Node として使用できるようになります。
3-5.GraphにNodeを追加する
先ほど作ったSampleGraphを開きます。
Graph Editor内で右クリックすると、追加できるNodeの一覧にNumberNodeが表示されます。
NumberNodeを選択すると、Graph上にNodeが配置されます。

コードでは、
public int value = 10;と書いただけですが、その変数がNode上に表示されています。
3.6.Outputを追加
ただし、現在のNumberNodeには接続口がありません。
そこでOutput Portを追加してみます。
NumberNodeを次のように変更します。
using XNode;
public class NumberNode : Node
{
public int value = 10; //記述済み
[Output]
public int output;
}[Output] を付けると、その変数がOutput Portとして登録されます。xNodeでは [Input] と [Output] をフィールドに付けることで静的Portを定義できます。
Graphを確認すると、下のようにポートが一つ増えているのが確認できます。

3-7.Inputを追加
今度は、NumberNodeから値を受け取るNodeを作ってみます。
新しく、スクリプトファイル:DisplayNode.cs を作成し、以下のコードを記述します。
using XNode;
public class DisplayNode : Node
{
[Input]
public int input;
}今度は、[Input] を付けています。
これによってInput Portが作成されます。
Graph EditorにDisplayNodeを追加すると、下のように表示されます。

3.8.Node同士を接続
Graphには現在、
umberNode の Output ○ 、
DisplayNode の ○ Input
があります。
NumberNodeのOutputからDisplayNodeのInputへドラッグして接続します。
すると、下のようにNode同士を線でつなげることができます。

これで、Node → Port → Connection → Node というxNodeの基本構造が見えてきました。
3-9.作ったGraphをC#から読み取ってみる
ここまでで、
SampleGraphを作る
NumberNodeを作る
DisplayNodeを作る
InputとOutputを追加する
Node同士をConnectionでつなぐ
ところまで確認できました。
ただし、ここまでではGraph Editor上にNodeを配置しただけなので、少し結果が分かりにくいところがあります。
そこで最後に、作成したGraphを通常のC#スクリプトから読み取り、Consoleに内容を表示してみます。
これによって「xNodeで作ったGraphやNodeを、ゲーム側のC#から利用できる」ことを確認してみましょう。
新しく、スクリプトファイル:GraphTester.cs を作成し、以下のコードを記述します。
public class GraphTester : MonoBehaviour
{
public SampleGraph graph; //Graphのインスペクターから割り当てる
void Start()
{
Debug.Log("Graphに登録されているNode数:" + graph.nodes.Count);
foreach (var node in graph.nodes) //Graphに登録されている全てのNodeを取得
{
Debug.Log("Nodeを発見:" + node.name); //Nodeの名前を出力
if (node is NumberNode numberNode) //NodeがNumberNodeであるかを確認
{
Debug.Log("NumberNodeのValue:" + numberNode.value);
}
}
}
}コードの解説
今回の GraphTester は、
public class GraphTester : MonoBehaviourとなっています。
これまで作った SampleGraph は NodeGraph、NumberNode や DisplayNode は Node を継承していました。
今回は通常のUnityスクリプトとして使用するため、MonoBehaviour を継承しています。
public SampleGraph graph;で、先ほど作った SampleGraph を Inspector から登録できるようにしています。
続いて、
graph.nodes.Countで、Graphに登録されているNodeの数を取得しています。
さらに、
foreach (var node in graph.nodes)を使って、Graphの中にあるNodeを1つずつ確認しています。
その中で、
if (node is NumberNode numberNode)によって、現在確認しているNodeが NumberNode かどうかを判定しています。
NumberNodeだった場合は、
numberNode.valueから、Nodeに設定されている値を取得します。
3-10.GraphTesterを実行する
Hierarchyで空のGameObjectを作成します。
名前は、GraphTester などにしておきます。
作成したGameObjectに、先ほどの GraphTester.cs をアタッチします。

Inspectorを見ると「Graph」という項目が表示されます。
ここへ、Projectウィンドウに作成した SampleGraph アセットをドラッグ&ドロップします。

これで準備は完了です。
UnityをPlayして、Consoleを確認します。
Graph内にNumberNodeとDisplayNodeが1つずつ配置されている場合は、たとえば次のように表示されます。

NumberNodeのValue:10 と表示されれば成功です。
Graph Editor上で作成したNumberNodeの値を、通常のC#スクリプトから読み取ることができました。
xNodeで作ったGraphは、ただEditor上で眺めるだけのものではありません。
Graphに保存したNodeやデータを、ゲーム側のC#スクリプトから読み取って利用できる、ということです。
3-11.まだConnectionから値を受け取っているわけではない
ここで1つ注意しておきたい点があります。
今回Consoleに表示した、
NumberNodeのValue:10は、NumberNodeとDisplayNodeをつないだConnectionを通して取得した値ではありません。今回は、
numberNode.valueによって、NumberNodeの値を直接読み取っています。
つまり「Graphの中にあるNodeをC#から取得して、そのNodeが持っている値を読み取れる」というところまでです。
では、Node同士をつないだConnectionを使って、本当に値を受け渡すにはどうすればよいのでしょうか。
そこで登場するのが、
GetValue()
NodePort
GetInputValue<T>()
などの機能です。
この部分は次回、実際にNode同士で値を受け渡しながら確認していきます。
4.今回のまとめ
今回は、Unityでノードベースのシステムを作るためのxNodeについて、導入から基本的なNodeの作成まで確認しました。

次回は、今回作成したConnectionを実際に利用します。
GetValue() や GetInputValue<T>() を使って、
NumberNode
Value = 10
│
▼
DisplayNode
Input = 10のように、Node同士で値を受け渡す仕組みを確認します。
さらに、2つのNumberNodeから値を受け取り、
Number 10 ──┐
▼
Add
▲
Number 20 ──┘
結果:30のような簡単な計算Nodeも作ってみます。
▼ Unity初心者向け記事まとめはこちら
こちらのマガジン「ミニゲーム作成講座 全8回セット」でもシーンの切り替えなどを活用して、初心者でも知識ゼロから作れるミニゲーム作成講座を紹介しています。

さらにステップアップの「スマホで遊ぶジャンプゲーム 8回セット」のマガジンもぜひご活用ください。

ファイブボックスでは、スクラッチやUnityの個別指導のオンラインレッスンを行っています。
ご興味のある方は当サイト、オンラインレッスンから、無料体験授業へお問い合わせ下さい。
いいなと思ったら応援しよう!
よろしければ応援お願いします! いただいたチップはクリエイターとしての活動費に使わせていただきます!