動機
UnityのVisualScriptingをさわってみてて、変数どこまでつかえるんだろう。と思ったことをメモ
特にSubGraph化(埋め込み・外部)したときの挙動がきになった
変数の種類
使いみちは個人の感覚です
種類 | スコープ | 使いみち? |
---|---|---|
Graph | そのグラフの中 | あまりつかわない |
Flow | 一連の処理の中 | 基本はこれを使う |
Object | 付属オブジェクトがわかればどこでも | publicなオブジェクトメンバー。基本はこれ |
Scene | シーンがわかればどこでも | 複数シーンで使うと面倒なやつ |
App | アプリの中ならどこでも | 便利だけど多用すると危険なやつ |
Saved | Appで終了時に保存される | 設定とかそんなやつ |
この中で、Flowだけは型宣言がありません
ネストしたらどうなる?
親グラフから埋め込みネストした先の変数
種類 | スコープ |
---|---|
Graph | 親GraphのGraph変数はみえません |
Flow | 親グラフのFlow変数みえる |
Object | 親グラフのThisObject変数は見える |
Scene | 見える(当たり前) |
App | 見える(当たり前) |
Saved | 見える(当たり前) |
当たり前ですが単独のファイルにしたGraphでは、
Flow変数は定義が保証されてない
Object変数はThisの中身が保証されてない
ので外で定義されてる前提にはできません
埋め込みと切り出しではSubGraphの意味が違うと思ったほうがよい
C#からVisualScriptingの変数をつかう方法
まあ、対象が存在してればとり方は同じ。
(Graph変数は使うことないと思う&GraphPointerとは・・・)
using Unity.VisualScripting;
// アプリケーション変数
//取得
Scene scene = Variables.Application.Get<Scene>("AppVariable");
// セット
Variables.Application.Set("AppVariable",scene);
// シーン変数
GameObject obj = Variables.Scene(scene).Get<GameObject>("SceneVariable");
Variables.Scene(scene).set("SceneVariable",obj);
// こんな使い方もある
Variables.ActiveScene().Set("SceneVariable",obj);
// オブジェクト変数
string str = Variables.Object(obj).Get<String>("ObjectVariable");
Variables.Object(obj).Set("ObjectVariable",str);
// グラフ変数 GraphPointerってどう取るんだ??
int i = Variables.Graph(graphPointer).Get(int)("GraphVariable");
ExistOnObjectとかExistInSceneとかメソッドがあるけど、OnObjectなのに、引数がObjectだけで変数名がないのでどうつかんだ状態(Sceneにも同じメソッドあるけどこちらも引数にSceneしかない)
雑感
まあとにかく資料が少ない。英語ですら少ない。
なんといっても名前をBOLTから変えたからVisualScriptingで検索しても出てこない。
BOLTでも仕様がかわってたりと、呼び名が変わってたりとか(SuperGraphとSubGraph)
どの変数をいつつかうのか、とか分かりづらいのか、
こんなやり取りも
アプリケーション変数は大人数での開発(VisualScripting自身が今の所大人数に不向きだけど)では、使い方気をつける必要があるけど、ゲーム中一つあればいいインスタンス等には有用じゃないですかねぇ
実際、Graphを書いてみると、線がごちゃごちゃになって見づらいので
Sequenceつかって横に長くならないように
フロー開始時点でフロー変数にコピっておく(ワーニング対策)
グラフ変数はつかわない(今のところ劣化版フロー変数)
処理ブロックごとに埋め込みネストしとく
のが綺麗になっていいかもしれない
Unityセンセイ、これからVisualScriptingどうするんですかね・・・
デバッグしづらいですよ(笑
おまけの備忘録
C#のクラスやメソッドをVisualScripting側で使ってて、仕様変更したときに、「どこでつかってた!?」となりがち。
(Graph同士でもよくある)
ちゃんとどこかに書いておけばいいのだけど、正直無理なんで今やってる探し方
Graphファイル自身はテキストファイルなので、VSCodeのターミナルで、Graphのおいてあるフォルダに移動し
Graphフォルダ% find ./ -type f | xargs grep -l "探したい関数名等" *.asset
これでつかってるファイル名が取れるのでそのグラフを開いて目視で探してます
Graph内の検索ほしいよ・・・
Graphは差分も取りづらいしね
さらにおまけ(23/05/20)
GraphからC#のスタティックメソッドをよびだしたとき、挙動がおかしかった
以下、現象と解決(?)方法の備忘
1)Object変数にGameObjectのListをつくり、インスペクタで入れておく
2)Graph内で上記変数を引数にC#のメソッドにわたす
3)C#のメソッドにわたった段階ではListの中身が空(ListはNullではない)
4)GraphでForループで回すとListの中身ははいっている
対策
C#メソッドにわたすまえにListオブジェクトの何らかのメソッドを呼ぶ(CountItemなど)
推察
Graph内でListにアクセスした段階で初めてListを初期化してるんじゃないか。
これはどっかに書いてあるのかなぁ・・・