Raspberlyのブログ

Raspberlyのブログ

Unityネタをメインとした技術系ブログです。にゃんこ大戦争や日常なども。そろそろブログタイトル決めたい

【アセット紹介】Roslyn C# - Runtime Compiler でScriptをランタイム実行する【Unity】

今回はアセットの紹介をしていきます。
紹介するのは「Roslyn C# - Runtime Compiler」。
ランタイムでC# Scriptをコンパイルし実行するアセットです。

 

 

お得なバンドル情報!

現在アセットストアでは、旧正月を記念したメガバンドルが発売中です!終了しました
厳選されたツール系アセットとアート系アセットが超お得に手に入るチャンス
今回紹介するRoslyn C# - Runtime Compilerも対象アセットです。
詳しくは下のバナーリンクからどうぞ。

f:id:Raspberly:20210209005108p:plain

 

どんなアセット?

ランタイムでC# Scriptをコンパイルし実行するアセットです。

#では、Roslynコンパイラを使用してアセンブリとC#スクリプトをランタイムで読み込むことができるため、プロジェクトにモッディングサポートやゲーム内プログラミングを簡単に追加できます。さらに、Roslyn C#には、コードのセキュリティ検証も含まれています。これにより、ロードされたコードが準拠しなければならないセキュリティ制限の数を指定できます。これには、不正な名前空間やタイプが含まれます。これにより、不明なソースからサードパーティのコードをロードする方がはるかに安全になります。

方向の意思決定を実行するコードを書くことによって迷路からマウスをナビゲートすることを目的とする小さなプログラミングベースのゲームが含まれています。

 

ドキュメントはこちら
コンピュータサイエンスの知識がある程度ないと厳しいのかも

 

 

開発環境

Unity 2020.1.17f1

Roslyn C# - Runtime Compiler ver1.4.2

 

 

インポートの確認

アセットインポート完了時はこんな感じです。
ドキュメントとしてUserGuid.PDFとScriptingReferenceがついています。

f:id:Raspberly:20210227033923p:plain

 

 

 

サンプルシーンの確認

Assets/RoslynCSharp/Examplesにサンプルシーンがあります。
ネズミさんの挙動をプログラミングし、ゴールまで導いてあげるゲームです。

f:id:Raspberly:20210227040826p:plain

左上に4つボタンがあり、プログラムの実行、停止、再実行、編集が行えます。

編集ボタンを押すとInputFieldが出てくるのでここにプログラムを入力します。
Example Scriptボタンを押すと実行可能な完成済みのプログラムを読み込みます。

 

 

 

クイックスタート

ドキュメントに従ってクイックスタートをやってみます。

パッケージのインポート

unitypackageをインポートします。
Unity 2018.1.0f2以降ならそのままインポートして問題ありません。
他バージョンの場合、PlayerSettingsのScriptingRuntimeVersion「.Net4.xEquivalent」になっていることを確認してください。

 

Exampleスクリプトの作成

以下のScriptを作成し、シーン内の適当なGameObjectにアタッチします。

using UnityEngine;
using RoslynCSharp;

public class Example : MonoBehaviour
{
        private ScriptDomain m_domain = null;

        //ロードするC#ソースコード
        private string m_source =
        "using UnityEngine;" +
        "class TestCode : MonoBehaviour" +
        "{" +
        " void SayHello()" +
        " {" +
        " Debug.Log(\"Hello World\");" +
        " }" +
        "}";

        void Start()
        {
               //ドメインの作成
                m_domain = ScriptDomain.CreateDomain("MyDomain", true);
               ////ソースコードをコンパイルしてロードします
                ScriptType type = m_domain.CompileAndLoadMainSource(m_source);

                //Testは継承するためgameObjectを渡す必要がある
                ScriptProxy proxy = type.CreateInstance(gameObject);

                proxy.Call("SayHello");
        }
}

 

「CompileAndLoadMainSource」はマネージアセンブリを生成するRoslynコンパイラを呼び出します。
その主なTypeAssembleが自動的に選択されScriptTypeとして返されます。
他のAPIの概要についてはスクリプトリファレンスを参照してください。

コンパイルと実行

Start時にTestCodeを実行し、SayHelloメソッドを呼び出します。

f:id:Raspberly:20210227041133p:plain
"Hello World"と表示され、ランタイムでC#Scriptが実行されているのが確認できました。

 

 

 

実際に試してみる

せっかくなので、InputFIeldを用意しプログラミングを書いて実行できる簡単なゲームもどきを作ってみます。

Sceneの作成

PlaneとCubeを置いておきます。

f:id:Raspberly:20210227031817p:plain

UIを配置します。
C#Scriptを記述するためのInputFIeldとScritp実行用のButtonを配置します。

f:id:Raspberly:20210227031847p:plain

Playerの作成

事前にPlayerとなるGameObjectを作成します。
今回はSD UnityChanを使用します。ColliderとAnimatorをいい感じに設定しておきます。

f:id:Raspberly:20210227032155p:plain

 

Scriptの作成

以下の「ScriptTester」Scriptを作成し適当なGameObjectにアタッチします。

using UnityEngine;
using RoslynCSharp;
using TMPro;

public class ScriptTester : MonoBehaviour
{
    public TextAsset m_templateSourceText;
    public TMP_InputField m_textField;
    private string m_source;
    private ScriptDomain m_domain = null;
    private ScriptType m_type;
    private ScriptProxy m_proxy;

    void Start()
    {
        m_textField.text = m_templateSourceText.text;
        m_domain = ScriptDomain.CreateDomain("MyDomain", true);
    }

    public void SourceExecute()
    {
        m_source = m_textField.text;
        m_type = m_domain.CompileAndLoadMainSource(m_source);
        m_proxy = m_type.CreateInstance(gameObject);
        m_proxy.Call("Execute");
    }
}

 

次に、テキストファイルを作成し以下のCodeTemplateを書いておきます。
ファイル名はScriptTemplateとかにしておきます。

using UnityEngine;

class CodeTemplate : MonoBehaviour
{
	void Execute()
	{
	}

}

 

コンポーネントの設定

先ほど作成したScriptTesterに他のオブジェクトを紐づけていきます。
TemplateSourceTextに、同じく作成したテキストファイルを紐づけます。
TextFieldにInputFieldを紐づけます。

f:id:Raspberly:20210227032404p:plain

 

ButtonのOnClickにはScriptTesterのSourceExecute関数を実行するようにします。

f:id:Raspberly:20210227032749p:plain

これで準備は完了です。

 

コードを書いて実行してみる

InputFieldにはテキストファイルに記述したテンプレートが最初から挿入されています。
ここにコードを書いてExecuteボタンを押すと、プログラム内のExecute関数が実行されます。

f:id:Raspberly:20210227033000p:plain

 

このようにResourcesのプレハブをInstantiateして、コンポーネントをアタッチするようなこともできます。

f:id:Raspberly:20210227040251g:plain

(はてなブログの容量制限のため画質を落としています)

 

 

「あなたもUnityはじめてみませんか?」のように
ゲーム内でプログラムを実行させるような作品が作れちゃうかもしれませんね!

www.youtube.com

 

 

 

まとめ

・Roslyn C# - Runtime Compilerを使うと、ランタイムでC#Scriptを実行できる

ScriptReferenceを見るといろいろなことができそうな予感

 

 

 

他のアセットの紹介記事はこちら↓

raspberly.hateblo.jp

 

 

 

※本記事にはAssetStoreアフィリエイトリンクが含まれています。

他、間違っている箇所、わかりにくい所がありましたらコメントにお願いします。