embed_var_save
文書の過去の版を表示しています。
組み込み時、Miniscriptから取得した変数を保存する方法
概要
MiniScript組み込み時に関数経由で変数を取得したい時があります。 少なくとも管理者は以下の理由により必要がありました。
* 敵スクリプトを書いてる時に特定タイミングで次に行動を指定したい * プレイヤーの行動に合わせて敵やボスの行動を変更したい
上記内容について、実装がうまく行ってるのでその内容を記載します。 なお、C#/C++について記載していますが、C++については大分内容が込み入ったものになります。
C#での実装
public class SampleClass: MonoBehaviour { //サンプルのノート。 public Value play_list; void intrinsic_define(){ f = Intrinsic.Create("get_list"); f.AddParam("note"); //リスト想定 f.code = (context, partialResult) => { var rs = context.interpreter.hostData as SampleClass; //ノート Value temp_value = context.GetVar("note"); rs.play_list = temp_value; return Intrinsic.Result.Null; } }
だいぶ簡単です。メンバ変数にValueを保管して、デリゲート処理で指定を間違わないようにすれば、楽に変数を格納可能です。 また、C#は値渡しがメインの機能で提供されているので、勝手に参照先が開放される等がなく管理は楽になっているかと思います。
つまりC#での実装においては以下の理由からあまり難易度が高くないと言えます。
- デリゲート機能があるため、クラス内のメンバ変数にアクセスができる
- 値渡しが主の機能になっているので参照先が開放される等のリスクを考慮しなくていい(auto使う場合はその限りではありません)
C++での実装
ではC++の実装でMiniScriptを使う場合はどうでしょうか。
結論から言うと、以下の理由でそう簡単にはいかないことが分かっています。
- C++にはデリゲート機能がなく、Valueについては起動しているVM内で保存する変数の「参照渡しになる」
- ValueクラスがVMへの参照しか持っておらず、実変数・文字列は全部VM上に持っている
- Context(VMがスクリプトを読んで計算する1回の処理)上での変数定義は保存しているが、基本的にはContext上でのローカル変数は開放されてしまう
現在ツールを開発していますが、上記問題に遭遇したため、色々資料を集めながらなんとか対応しました。 以下にその対応方法を記載します。
変数を受け取るための実装
embed_var_save.1720749309.txt.gz · 最終更新: 2024/07/12 10:55 by machiaworx