====== 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()メソッド等の変数として取得出来るメソッドに変換して、元の値に格納していく形になります。