ユーザ用ツール

サイト用ツール


embed:tutorial1

UnityへのMiniscriptの埋め込み(組込)入門

資料

概要

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

embed/tutorial1.txt · 最終更新: 2023/01/15 10:16 by machiaworx