はじめに
この記事では C# のプログラム上から C# のコードをスクリプトとして使う方法を紹介します。
過去の私のように学生でゲーム作ってます!な方に役立つといいなと思っています。
また、環境は Windows で VisualStudio を前提としていますのでご了承ください。
どんなときにつかうのか
たとえば、RPG ゲームの村人の行動の制御をするとしましょう。
単純な行動と会話のみであれば、最低限の継承や設定でなんとかなると思いますが、移動パターンの制御、話しかけたときの返答の制御、主人公の持ち物で会話が変わる…
などと凝ったことをしようとすると、数値や文字だけで制御するのは難しいです。
そんなときに、スクリプトが使われるわけですね。
スクリプトとして読み込むようにすれば、動きを変えるたびに毎回ゲーム全体をビルドする必要もありませんし、制御の内容を一緒にゲームを作る友人に任せるということもできます。
ゲームのスクリプトとしてよく Lua などが使われてきたのですが、ゲーム制作でいっぱいいっぱいで新しく覚えるのは大変ですし、ましてやスクリプトを友人に任せるなんてできないです。
しかし、C# には Roslyn があります!
Roslyn は C# で書くことができ、割と簡単に動いてくれるので、新しく覚えることは少なく済むでしょう。
つかう準備
Roslyn は .Net4.6 以上でないと動いてくれないようなので、プロジェクトを .Net4.6 以上にしてあげてください。
あとは NuGet で Microsoft.CodeAnalysis.CSharp.Scripting をインストールすれば準備完了です。
つかってみる
基本的には、
- スクリプトを書いたファイルを読み込む
- スクリプトの環境を準備する
- スクリプトを実行する
- 実行結果を取得する
といった感じになります。
以下のプログラムは Roslyn の紹介に必要な最小限 +α 程度のものとなっています。
実行するとコンソールに Child! と表示してくれるはずです。
こちらが読み込んで実行する側のプログラムです。
重要なのは、WithReferences(Assembly.GetEntryAssembly()) で参照を追加している部分、
result.ReturnValue で実行結果を取得している部分です。
using System; using System.IO; using System.Reflection; using Microsoft.CodeAnalysis.CSharp.Scripting; using Microsoft.CodeAnalysis.Scripting; namespace MyRoslyn { class Program { static void Main(string[] args) { var text = File.ReadAllText("script"); var script = CSharpScript.Create(text). WithOptions( ScriptOptions.Default. WithReferences(Assembly.GetEntryAssembly())); var result = script.RunAsync().Result; var value = result.ReturnValue; Console.WriteLine(value.Method()); } } public abstract class Parent { public abstract string Method(); } }
こちらが読み込まれる側のスクリプトです。
Parent クラスを継承元に利用できている点が重要な点ですね。
唐突に return などと書けるのがなかなか面白いです。
using MyRoslyn; public class Child : Parent { public override string Method() { return "Child!"; } } return new Child();
今回のプログラムでは実行結果は簡素なものですが、このプログラムを応用すれば RPG の村人の制御などのようなものはすぐでしょう。
最後に
本当はスクリプト用のディレクティブやオプション、リゾルバを説明しようかとも思ったのですが、最小限かつある程度使えるもの を目指した紹介にしてみました。
やろうと思えばスクリプトからなんでもできて楽しいので、ぜひ触ってみてほしいです。