Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
14
Help us understand the problem. What is going on with this article?
@RyotaMurohoshi

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

More than 5 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さん、ありがとうございました。

14
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
RyotaMurohoshi
プログラミングが大好きで、 C#が大好きで、 .NETが大好きで、 LINQが大好きで、 JVM言語が大好きで、 ゲームで遊ぶことが大好きで、 ゲーム開発が大好きで、 頑張るのが大好きで、 Unityが大好きだったから...!

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
14
Help us understand the problem. What is going on with this article?