VisualScriptingでゲーム作ったのでまとめと所感

# 前置き
ノードでのプログラムアセットとしては依然からBoltが有名でした

https://assetstore.unity.com/packages/tools/visual-scripting/bolt-163802

Unity2021からVisualScriptingとして正式に取り込まれています

https://unity.com/ja/features/unity-visual-scripting

VisualScriptingを触って簡単なゲームを作ったので使い方をメモしておきます

![ボクシングゲームのスクショ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7680/8ce5c884-1224-d133-accb-529830cd2f15.png)

https://github.com/tsune2ne/BoxingGame

# 基礎概念
## ScriptGraph
ノードスクリプト
GameObjectにScriptMachineをAddComponentしてNewを押してScriptGraphを追加、もしくはProjectで追加したScriptGraphをGraphに設定することで実行される
デフォルトではなにもないのでEventノードを手動で追加して処理を作る

![VS_ScriptGraph_debuglog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7680/0ff6e770-2dab-e5ff-7ef3-fcffbdd39cbd.png)

Eventノードには同じみのOnStartやOnUpdateもある
ノード自体はUnityのC#コードでお馴染みの関数が用意されているので慣れれば難しくはない

めんどくさいけど

## StateGraph
ScriptGraph用のステートマシン
GameObjectにStateMachineをAddComponentしてNewを押してStateGraphを追加、もしくはProject Viewで追加したStateGraphをGraphに設定する

状態遷移を管理することができるステート
ステートの中身はFlowGraphみたいに使える
StateMachineを知らない人はAnimatorみたいなものと考えてOK

### キャラアニメーションのStateGraph
![VS-StateGraph-boxer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7680/70e35cca-85bc-5370-9c3d-0630d75ed9d8.png)

Idleステートから始まり、左のObject Variableの値が変わることで別のStateに移動する

### Idleステートの中身
![VS-ScriptGraph-boxer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7680/9bafa0f4-08be-bd68-9b5d-3f0dd8051bfa.png)

ScriptGraphの中には「OnEnterState」「OnUpdate」「OnExitState」の3種のEventノードがデフォルトで設定されている
Stateに入ってきたらOn Enter Stateイベントが発火してTimerノードにイベントが流れる


# こだわった使い方をしたい
## C#コードで自作ノードを使う
namespaceに入れなければ自動コンパイルしてScriptGraphで呼び出せる
namespaceに入ってる場合はProject Settings > Visual ScriptingのNode Libraryにnamespaceを追加したらScriptGraphから呼び出せる

自作ノードをプログラマーが作って、デザイナーがVisualScriptする未来が見える

## State移動どうやるの？
Variableを追加してTransitionでVariableをUpdateでチェックしてState移動した
プログラマーとしては気持ち悪い

## EnumをScriptGraphで使えるようにしたい
Enumを定義して、Project Settings > Visual ScriptingのType Optionsに追加する
StateごとにEnumを割り振る場合、C#を介さずに増やしたいのでVisualScriptingだけで追加できるようにしてほしい

## C#からVariableの値を変更
Variable.declarations のkeyを検索してvalueを上書きすると反映される

```c#
[SerializeField] Variables variables;
void SetVariable(string key, object value)
{
    foreach (var v in variables.declarations)
        if (v.name == key)
            v.value = value;
}
```

# 所感
## メリット
・ノードのフローがビジュアルで見える。StateMachineも見やすい。このStateMachineは普通にC#コードでも使えるようになってほしい
・エラーが起きると該当ノードが赤色になる
・ノードスクリプティングではビルド時間なしに起動確認できる。しかもPlay中に数値変更する
と反映される
・コードの感覚でスクリプティングできる。コードでできることは大体できる
・ロジックのAB化ができる。バイナリ更新せずに挙動が変えられる！

## デメリット
・なんでもできてしまう。非エンジニアには機能制限して渡したい
・リファクタがしにくい。参照探しやリネームができない。綺麗な設計にするにはかなり気を遣う。

## 改善してほしい点
・UnrealEngineみたいなブレークポイント
　・非プログラマーがデバッグするのにはまだ難しい。ブレークポイントを正式対応してほしい。
・Enumの追加を気軽にしたい
　・StateMachineでStateを移動するのにVariableを使うしかないが、StateごとにVariableが増えるのでInspectorが汚れる
　・EnumでStateを一括管理してInspectorのVariableを短くしたい
・VariableにGraphとObjectがあるが、StateMachine内のみ共有する変数が欲しい
　・StateMachine内でしか使わない変数が多い

## BoltとVisualScriptingの違い
・大きな変更点はない
・BoltのSetupWizardがなくなった
・BoltではメニューバーからType OptionsやNode Libraryを指定していたが、VisualScriptingではProjectSettingsに移動した
・PrefarenceにもVisualScriptingの項目があり、見た目の設定を変えることができる
・Graphで最大ズームしなくてもコメントの端を掴んで拡張できる
・GraphのズームがスクロールじゃなくてCtrl-スクロールになった。正直使いにくい。

# 考察
UnrealEngineのブループリントほどではないですが使えるように整備されています
ですがやはりゲーム全体をVisualScriptingで作るのはメンテナンスコストが高いため現実的ではないと思います

しかしグラフィカルにデバッグできる点、アセットとしてDLできる点などから
レベルデザイナーに部分的に実装してもらうのがよさそうです

将来的にもっとデバッグ能力やメンテナンス能力が向上すれば
プログラマーはノード追加に徹して、ゲームの大部分を非プログラマーが作成するのも可能ではないでしょうか

<!--
# 資料
https://learn.unity.com/project/bolt-roll-a-ball-tutorial

↑↑公式チュートリアル

https://learning.unity3d.jp/5833/

↑↑公式解説動画

https://tech.mirrativ.stream/entry/2022/04/18/180029

↑↑Mirrativの所感が入ってて〇



https://booth.pm/ja/items/2362198

↑↑Boltでオリジナルノードを作りたいなら参考になるかも（読んでない）

https://creator.game.cyberagent.co.jp/?p=6903

↑↑なにか参考になるかも

https://littlewing.hatenablog.com/entry/2020/09/04/113940

https://note.com/kabineko/n/nf1fc0734ad26
-->