====== UnityへのMiniscriptの埋め込み(組込)入門 ======
==== 資料 ====
https://miniscript.org/files/MiniScript-Integration-Guide.pdf
==== 概要 ====
Unity上でMiniscriptを組み込む手順を書く。
元々MiniscriptがUnityへの組込を想定して作られたとのことで、割と導入は整備されてます。
==== 手順 ====
まずMiniscriptのソースコード一式をUnityのプロジェクトに追加した後、以下のコードを書きます。
public string loadText;
public TextAsset textAsset;
void Start(){
loadText = textAsset.text;
RunScript(loadText);
}
public void RunScript(string sourceCode) {
string extraSource = "ship.reset = function(); self.x=0; self.y=0; self.rot=0;end function\n";
interpreter.Reset(extraSource + sourceCode);
interpreter.Compile();
ValMap data = new ValMap();
data["x"] = new ValNumber(transform.localPosition.x);
data["y"] = new ValNumber(transform.localPosition.y);
data["rot"] = new ValNumber(transform.localRotation.z);
interpreter.SetGlobalValue(globalVarName, data);
}
ここで重要なのは、interpreterクラスで実行している処理と、そのあとのバインド処理になります。
interpreterクラスのReset関数にてソースコードを読み込み、Compile関数にて処理を利用可能な状態にしている、という形です。
また、「ValMap」というクラスを初期化してますが、これがMiniscript側で管理できる変数を保管するクラスみたいなんですね。
ここに参照先を指定して、言ってしまうと変数をバインドする形になります。
余談ですがグローバル変数みたいな形でも管理が出来る模様(SetGlobalValueってメソッドで行うみたいですね)
ソースコードの実行と変数の反映
void Update(){
try{
//interpreter.Restart();
if( !interpreter.Running())
interpreter.Restart();
interpreter.RunUntilDone(1.0f);
}catch (MiniscriptException err) {
#if UNITY_EDITOR
Debug.Log("Script error: " + err.Description());
#endif
}
UpdateFromScript();
}
public void UpdateFromScript() {
ValMap data = null;
try {
data = interpreter.GetGlobalValue(globalVarName) as ValMap;
} catch (UndefinedIdentifierException) {
Debug.LogWarning(globalVarName + " not found in global context.");
}
if (data == null) return;
Transform t = transform;
Vector3 pos = t.localPosition;
Value xval = data["x"];
if (xval != null) pos.x = xval.FloatValue();
Value yval = data["y"];
if (yval != null) pos.y = yval.FloatValue();
t.localPosition = pos;
Value rotVal = data["rot"];
if (rotVal != null) t.localRotation = Quaternion.Euler(0, 0, (float)rotVal.FloatValue());
}
ここでやってることは、スクリプトの実行と、Valueクラスからデータを参照し、値をバインドした変数に代入しています。
スクリプトの実行は、RunUntilDoneメソッドで行います。
これは、指定秒数までを許容し、それ以上だと途中で打ち切るみたいです。(オプションで指定秒数まで待つことも可能)
また、処理は毎フレームで処理してもらうのが重要なので、常時Running()状態にしてます。
Running状態とは、コンパイルして動かす準備ができたという事みたいです。
実行した後だとRunning()がFalseに切り替わるため、Restart()関数を実行することでRunning()がTrueを返すようにします。
ValueクラスはMiniscriptで持っているクラス名、このクラスからFloatValue()メソッド等の変数として取得出来るメソッドに変換して、元の値に格納していく形になります。