【Unity】xNodeの実践的な使い方

　xNodeの実践的な使い方について丁寧に解説している日本語サイトが少ないので書きました。初めてのQiita記事なので、おかしいところはご指摘ください。**実践例など順次更新していきます。**
# xNodeとは
xNodeは無料のノードエディターフレームワークです。独自のノードを追加してノードベースのプラグインなどを作ることができます。
MITライセンスなので、自分のアセットに同梱して配布できます。
https://github.com/Siccity/xNode

Unity対応バージョンは2019.4.0以上です。
# 導入と簡単な説明
https://ghoul-life.hatenablog.com/entry/2019/03/04/224229
こちらのサイトをご覧ください。

# 実践1　ノードに入力された文字をログに出力する
<ol>
<li>NodeGraphの作成</li>
Nodeを置くためのNodeGraphを作成します。右クリック > Create > xNode > NodeGraph C# Script で新しいノードグラフスクリプトを作成し、適当にSampleNodeGraphと名前をつけます<br>

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358342/c2002a1f-82d9-7fc5-22e7-7cae966138cf.png">

すると、右クリック > Create の欄に、新しくSampleNodeGraphが作成できるようになります。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358342/083d2bbc-89f2-9b1c-36d1-9b5bdfd63520.png">

作成してダブルクリックすると、このような画面が出てきます。これがノードグラフで、この上にノードを置いたり繋げたりして使います。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358342/dc96c38a-44dc-536e-5cb8-4b6c743a7d93.png">

<li>Nodeの作成</li>
ノードを作成します。右クリック Create > xNode > Node C# Script でノードスクリプトを作成します。ノードスクリプトを2つ作成し、HeadとLogと名前を付けます。

```cs:Head.cs
using XNode;

public class Head : Node
{
    [Output(connectionType = ConnectionType.Override)]
    public Node nextNode;
}
```
```cs:Log.cs
using UnityEngine;
using XNode;

public class Log : Node
{
    [Input(ShowBackingValue.Never, ConnectionType.Override)] 
    public Node beforeNode;
    [Input(connectionType = ConnectionType.Override)] 
    public string log; // 表示する文章を入力
    [Output(connectionType = ConnectionType.Override)] 
    public Node nextNode;
}
```
保存後、ノードグラフで右クリックすると作ったノードが追加できるようになっています。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358342/bf3cffe6-0486-f7de-04b6-6d6905811054.png">

<li>ノードの情報を使うスクリプトを作成</li>
1.で作ったSampleNodeGraph.csを開いて以下のように書き換えます。

```cs:SampleNodeGraph.cs
using UnityEngine;
using XNode;

[CreateAssetMenu]
public class SampleNodeGraph : NodeGraph {
    public Node current; // 
    public Node HeadNode() // Headノードを探します。
    {
        Head result = null;
        foreach (var node in nodes) // NodeGraph上のすべてのノードはnodesの中にあります。
        {
            result = node as Head; // nodeがHeadノードだったらresultに入れます。
            if (result != null) // 中身がある＝nodeがHeadノードだったらループを抜ける。
            {
                break;
            }
        }
        return result;
    }
}
```



```cs:ShowLog.cs
using UnityEngine;
using System;
using XNode;

public class ShowLog : MonoBehaviour
{
    public SampleNodeGraph graph;
    bool nodeContinues = true;
    void Start()
    {
        ShowLogNode();
    }

    public void ShowLogNode()
    {
        graph.current = graph.HeadNode();
        NextNode();
        while (nodeContinues)
        {
            Log obj = (Log)graph.current;
            Debug.Log(obj.log);
            NextNode();
        }
        nodeContinues = true;
    }

    void NextNode()
    {
        foreach (NodePort p in graph.current.Ports)
        {
            if (p.fieldName == "nextNode")
            {
                try
                {
                    graph.current = p.Connection.node as Node;
                    // nextNodeに繋がっているノードに移動(currentノードに入れる)
                }
                catch(NullReferenceException e) // nextNodeに何も繋がっていなかったら
                {
                    nodeContinues = false; // 上のwhile文を出ます
                }
            }
        }
    }
}

```
これを空のゲームオブジェクトにアタッチして実行します。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358342/ee9be33a-1fba-c72a-1a8c-86f65d170142.png">

ノードにつなげた通りに表示されました。

## おまけ
こちらのサイトを参考にして、インスペクターに実行ボタンを作りました。
https://kan-kikuchi.hatenablog.com/entry/CustomEditor_Button

![ss6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358342/55d28591-bb8e-3b72-51ee-08901d1edbfd.png)




</ol>


# 参考
https://www.youtube.com/watch?v=7E1EqekXnwQ