====== より実践的なソース組み込み ====== ==== Unityのプロジェクトを新規作成 ==== 2Dにする理由はないですし、3Dで問題ないです。 ==== Miniscriptのソースコード用意 ==== それではプロジェクト内にMiniscriptのC#ファイルを読み込ませてください。 フォルダの中に格納するほうが他のソースと判別しやすくて管理が楽です。 {{:embed:20230116_source.png|}} ==== オブジェクト準備 ==== 以下の画面の様に「Cube1個、Text1個」を用意してください。 {{:embed:20230116_game1.png|}} ==== 実装 ==== 以下のソースをCubeにアタッチしてみてください。 using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using Miniscript; using TMPro; public class ScriptMover : MonoBehaviour { public TMP_Text tmp_stage_frame; private string loadText; public TextAsset textAsset; public Interpreter interpreter; //ここにグローバル変数を格納するクラス名を指定してください。 public string globalVarName="ship"; private int frame=0; void Start(){ loadText = textAsset.text; interpreter = new Interpreter(); interpreter.hostData = this; //標準出力先の指定 interpreter.standardOutput = (string s,bool t) => Debug.Log(s); interpreter.implicitOutput = (string s,bool t) => Debug.Log($"implicit {s}"); interpreter.errorOutput = (string s,bool t) => { //エラーログ出力。(Unity側のエラーとして動く) Debug.LogError(s); }; //組込関数定義のための変数 Intrinsic f; //文字列をテキスト枠に反映させる f = Intrinsic.Create("change"); f.AddParam("str", ""); f.code = (context, partialResult) => { var rs = context.interpreter.hostData as ScriptMover; rs.tmp_stage_frame.text = context.GetVar("str").ToString(); return Intrinsic.Result.Null; }; //ソースコードの起動準備を行う。 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["cnt"]=new ValNumber(0); data["x"] = new ValNumber(this.transform.localRotation.x); data["y"] = new ValNumber(this.transform.localRotation.y); data["rot"] = new ValNumber(this.transform.localRotation.z); //グローバル変数の定義。今回は1個のマップにまとめてる interpreter.SetGlobalValue(globalVarName, data); } void Update(){ //コンパイルしたソースコードを実行する try{ 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; //CubeのRotationを変更する Value xval = data["x"]; Value yval = data["y"]; Value rotVal = data["rot"]; if (rotVal != null) t.localRotation = Quaternion.Euler(xval.FloatValue(), yval.FloatValue(), (float)rotVal.FloatValue()); //全体フレーム数を加算する Value cntval=data["cnt"]; frame=cntval.IntValue(); } } 終わったらCubeからテキスト部分を参照しておいてください。 ==== Miniscript言語で書いたソースコード用意 ==== 以下の内容のテキストファイルを用意してください。 serif=["This is Miniscript's test.","This is sample."] ship.x=ship.x+1 ship.rot +=2 ship.cnt+=1 change(serif[(ship.cnt/600)%2]) 終わったらCubeから作ったソースコードを参照しておいてください。 ==== 動かしてみましょう ==== 見事にCubeが回転したり文字が更新したりされるはずです。 {{:embed:20230116_output.png|}}