見出し画像

【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の個別指導のオンラインレッスンを行っています。
ご興味のある方は当サイト、オンラインレッスンから、無料体験授業へお問い合わせ下さい。

いいなと思ったら応援しよう!

ファイブボックス よろしければ応援お願いします! いただいたチップはクリエイターとしての活動費に使わせていただきます!