F#
Unity3D
Unity
Xamarin
.NETFramework

初心者がF#をUnityで使ってみた!

More than 3 years have passed since last update.


はじめに

この投稿はF#アドベントカレンダー2014の22日分の投稿です。

別にF#アドベントカレンダーは、Hello World!でもいいとのことでしたので、初心者がHello World!してみました。Unityゲームエンジンで。

@pocketberserkerさんさんが、こちらの記事でUnityでF#を使われている記事を見て、まねして私もやってみました!F#の勉強会もだいぶ前ですがに行ったし、何もしないのはもったいないかなと、Hello World!ですがやってみました!

繰り返しになりますが、F#ド初心者です。

間違いの指摘、良くないところのアドバイスなどお願いします!


UnityでF#を使ってみた!

Xamarinを使ってF#のライブラリを作り.NET 2.0向けのDLLを作成して、それをUnityで利用してみます。

(Xamarin Studioのバージョンは5.5.4で、Macでやっています。)

(間違いの指摘、良くないところのアドバイスなどお願いします!またこうした方がいいなどありましたら、教えていただけると嬉しいです。)


ソリューション・プロジェクトの作成

まずF#のライブラリプロジェクトをXamarinStudioを使って作成します。


  1. Xamarinを起動し、メニューからFile > New > Solution を選択します

  2. 表示されたウィンドウで、F# > Library を選択します(下図参照)

  3. Locationを適切に設定し、NameをFsharpUnityLibraryとし、OKボタンを押します

  4. プロジェクト内のComponent1.fsを次のように編集します

image0.png


編集後のComponent1.fs

namespace FsharpUnityLibrary

type FsharpSampleClass() =
member this.Message = "Hello F# World!"
member this.MyBigInterger = 18446744073709551616I
member this.MyTuple = ("Hello", 7)



DLLの作成

次にUnityで使えるように、DLLを作成します。


  1. プロジェクトを右クリックし、ポップアップからOptionsを選択します

  2. 表示されたウィンドウで、Build > GeneralでTarget frameworkをMono/.NET 2.0に変更します

  3. 次に同じウィンドウで、Build > Compiler を選択します

  4. Command line parametersに、--standaloneと入力します(下図参照)


  5. System.CoreSystem.Numericsのリファレンスを削除します(下図参照)

  6. Buildします(今回はDebug)


  7. ソリューションのルート/FsharpUnityLibrary/bin/DebugFsharpUnityLibrary.dllが生成されています

image1.png

image2.png


Unityでの利用

さきほど作ったF#のDLLをインポートして、UnityでF#を使ってみます


  1. Unityプロジェクトを作成します。

  2. 先ほど作成したDLLをソリューションのルート/Assets以下にコピーします

  3. 次のようなSample.csを作成します


  4. Sample.csを任意のシーンの任意のGameObjectに付与し、シーンを再生します

  5. Consoleウィンドウに後述のログに出力されることを確認します


Sample.cs

using UnityEngine;

using FsharpUnityLibrary;

public class Sample : MonoBehaviour
{
void Start ()
{
FsharpSampleClass fshapSample = new FsharpSampleClass();

string message = fshapSample.Message;
Debug.Log (message);

System.Numerics.BigInteger myBingInteger = fshapSample.MyBigInterger;
Debug.Log (myBingInteger);

System.Tuple<string,int> myTuple = fshapSample.MyTuple;
Debug.Log (myTuple);
}
}


Hello F# World!

18446744073709551616
(Hello, 7)


ちょっと考えてみた!

さらっとF#のコードについてさらっと流しましたが、意図があってのコードです。

F#側のコードとUnityのC#側のコードを再掲します。


編集後のComponent1.fs

namespace FsharpUnityLibrary

type FsharpSampleClass() =
member this.Message = "Hello F# World!"
member this.MyBigInterger = 18446744073709551616I
member this.MyTuple = ("Hello", 7)



Sample.cs

using UnityEngine;

using System.Collections;
using FsharpUnityLibrary;

public class Sample : MonoBehaviour
{
void Start ()
{
FsharpSampleClass fshapSample = new FsharpSampleClass();

string message = fshapSample.Message;
Debug.Log (message);

System.Numerics.BigInteger myBingInteger = fshapSample.MyBigInterger;
Debug.Log (myBingInteger);

System.Tuple<string,int> myTuple = fshapSample.MyTuple;
Debug.Log (myTuple);
}
}


18446744073709551616Iに注目してください。(最後は英字のI(アイ)ですよ) このように大きい正の整数ではulong(UInt64)型を使うことを考えると思います。さてulong(UInt64)型の表現範囲は、0から18446744073709551615です。F#側の18446744073709551616は、ulong(UInt64)型の表現範囲より1大きいですね。ここでは、System.Numerics.BigInteger型を使ってulong(UInt64)が表せない正の整数を表しています。I(アイ)はBigIntegerの接尾詞です。

また、MyTupleではタプル(System.Tuple<T1, T2>)型を使っています。

何か気づきませんか?

Unityでは、System.Numerics.BigInteger型やタプル(System.Tuple<T1, T2>System.Tuple<T1, T2, T3>など)を普通は使うことは出来ません。それらは.NET Framework4.0で加わったものだからです。

Unityはmonoを使っています。.NET Framework 4.0相当のmonoバージョンは2.10らしいです(クラスライブラリの一部はそれより前でも使えるんですかね?勉強しておきます)。Unityはだいぶ古いmonoをベースにしています。(2.6.5?でもコミット的には、2.6.4の子孫でないっぽいし、そもそも2.6.5ってリリースされていないし) そのため、Unityでは.NET Framework 4.0で追加された、BigIntegerやタプルを通常は使うことはできません。

ところで、F#は.NET Framework 2.0でも動くようになっています。F#で.NET Framework 2.0で動作させるようターゲットなどを設定した場合、コアライブラリ (FSharp.Core.dll)の中に、F#開発に必要なSystem名前空間(BigIntegerやタプル、その他いくつかのクラス)の、.NET 4.0 APIと同じAPIがいくつか含まれるそうです。(くわしくはこちら)。そのため、Assets以下においたF#ライブラリのDLL内に含まれているF#コアライブラリのおかげで、UnityでもBigIntegerやタプルが使えるようです。


まとめ

実際に今後F#をUnityで使うかは未定ですが、Hello WorldですがF#をUnityで動かしてみました。

今までなぜF#がUnityで動くか疑問でした。理解するため、monoや.NETについてちょと勉強しましたが、その感想は

「F#、.NET 2.0から動くん?」「.NET Frameworkすげえ!」「CLIすげぇ」「ILの互換性ぱねぇ、.NET 2.0からの互換性ぱねぇ、変性が2.0の時点で入ってる!」「mono、Xamarinありがてぇ!」

という感じです。まだまだしっかりと理解できていませんので、もうしこし理解がすすんだらまとめたいと思います。

F#成分少なくてすいません。初歩的すぎてすいません。

また、私のアドカレ本来の担当日をカバーしてくださった@bleisさん、お手をわずらわせてしまった@pocketberserkerさん、ありがとうございました。