FieldWalker

Diarkis Unity SDKサンプルアプリケーション

ネットワークミドルウェアである Diarkis が提供する Unity Engine ベースのサンプルアプリケーションです。MatchMake、DirectMessage、異なるプロトコル(UDP、TCP、P2P)を使用したプレイヤー間のデータ同期など、さまざまな機能が含まれています。 Diarkis 製品の詳細については Diarkis Website を参照してください。

フォルダの説明

  • Core Diarkis C# SDKをインストールします

    • Client Diarkis Module (Diarkis Core Library を使用するための C# クラスとヘルパー)

      • Data データ構造関連クラス

      • Events イベント関連クラス

      • Logging ロギングシステムに関連するクラス

      • Modules モジュール・ベース・クラス (Diarkis Core Library と相互作用するコードを含む)

      • System システム関連クラス (メモリ管理など)

      • Utils Diarkis型を使用するための各種ヘルパー

    • Interop Diarkis Native Code を呼び出すために自動生成された C# ファイル (これらのファイルを変更することは推奨されません)

    • CustomCommands 開発者は、ここのファイルを使用してカスタムコマンドを定義できます

      • json_definitions カスタムコマンドの構造を定義する json ファイル

      • custom カスタムコマンドの構造を定義する json ファイル

    • Libraries C++ で作られた Diarkis Native Code (Diarkis Core API)

  • Misc その他ファイル(ライト、入力システムなど)

  • Models 3D モデルファイル

    • Animations キャラクター用アニメーションファイル

    • Materials マテリアルファイル

  • Prefabs プレハブファイル (例: DiarkisPlayer、Grid など)

  • Scenes Unity のシーンファイル。

  • Scripts Unity 関連スクリプト

    • Plugin Diarkis プラグイン スクリプト

      • Callbacks Diarkis イベントへのコールバックを登録するスクリプト

      • Common 各シーン共通のスクリプト(Diarkis SDK とのインタフェースを持つシングルトンクラスの DiarkisNetworkManager を含む)

      • MainGame MainGame シーン用スクリプト(3D環境におけるプレイヤーの同期)

    • Sample Diarkis サンプルスクリプト

      • SceneManagers シーン固有のクラス

      • UI ユーザーインターフェイススクリプト (ボタン、トグルなど)

  • Textures 画像ファイル

プロジェクトをロードする

Unityプロジェクトで、Window>Package Managerでパッケージマネージャを開き、+をクリックし、Add Package From Diskで、Diarkisサンプルフォルダのルートにあるpackage.jsonファイルを選択します。

LTS の Unity バージョンを使用することをお勧めします(最終アップデートでは2022.3.20f1)。 これで、プロジェクトを Unity Editor で開くことができます。

タイトルシーンファイル (Assets/Scenes/DiarkisSample_1_Title.unity) を選択します。 ツールバーから再生ボタンをクリックすることでサンプルを実行することができます。

MacOSにおけるライブラリのセキュリティエラー

MacOSでプロジェクトをロードしているユーザは、ライブラリが信頼できないというポップアップ通知が表示されることがあります。 この場合、ウィンドウを閉じずにシステム設定>プライバシーとセキュリティを開き、とにかく許可ボタンを押してください。各ライブラリに対してこの操作を行う必要があるかもしれません(ただし、各ライブラリにつき1回のみ)。この操作を行わないと、Diarkisのライブラリが実行できなくなり、サンプルにランタイムエラーが表示されます。

プレイモード中のリコンパイルを無効にする

シーン解説

タイトル

このシーンはサンプルの初期シーンで、Diarkisサーバーとの接続を設定するために様々な入力を提供することができます。

Item
Description
Example

Host

Diarkis Http サーバの EndPoint URL

asia-northeast1.diarkis.io (http:// は不要です ) / 192.168.XXX.XXX:7000

ClientKey

Client Key (必要な場合は指定する)

XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

UID

ユニークな User ID

Diarkis203

RandomUID

ユニークな User IDをランダムに自動生成(unique GUID)

0f0b66aa-8d45-4505-9208-c41d975a0c65

ServerType

使用する Diarkis サーバの通信プロトコルを指定する

UDP or TCP

SelectFeature

この画面から、各 Diarkis モジュール に関する機能を選択できます。

Room

この画面は、Diarkis Room Module を使用します。Room は、この画面から Create、Join、RandomJoin で部屋に入室することができます。

Item
Description
Example

MaxMember

Room の最大入室人数

4

AllowEmpty

ユーザーが部屋にいない間、部屋の存在を許可する。

true

TTL

部屋に誰も居なくなった後の部屋の存続時間。

60

Interval

Broadcast, MessageTo のメッセージのサーバでの送信間隔。この間隔分メッセージはバッファリングする。

200

Join Existing Room

RoomID を指定して入室する。 (上記の設定は使用しない)

Join Random Room

上記の設定を使ってランダムなルームに参加し、既存のルームが見つからない場合は新しいルームを作成する。

Create Room

上記の設定を使用してルームルームを作成し、参加する。

MainGame - Room

この画面は Room が参加に成功すると表示されます。Diarkis Room Module を通じてメッセージを送受信することで、プレイヤーやオブジェクトの位置を同期されます。

Item
Description
Example

My UID

自分のローカルキャラクタの UserID。

Diarkis-Test

Room ID

入室している Room の ID。

17b39a74e5fff52c7f0000011fa4

Owner UID

Room オーナーの User ID 。

Diarkis-Test

Members

現在 Room に入室しているメンバー。

Diarkis-Test, ...

Broadcast/Send

Room 内の全員にメッセージを送信する。User ID を指定した場合は、そのユーザーのみにメッセージが送信する

Leave

Room から退室して、前の画面に戻る。

Start P2P

他の Room メンバーとのP2P通信を初期化する。一度設定すると、メッセージの送受信は Diarkis Room Module ではなく Diarkis P2P Module を使って行われます。これにより、通信速度が向上する可能性がある。

Create Sphere/Cube

プレイヤーの近くに新しい object を生成して位置を同期する。

Clear All Objects

Room 内の作成された Object をすべて削除する。

Clear My Objects

Room 内の自分が作成した Object をすべて削除する。

MainGame - Field

この画面は Diarkis Field Module の3D表現を表示している。Field 通信は Join や Create のような事前コマンドを必要しません。Feild は1つのサーバタイプに1つしか存在せず、ユーザーは一度に1つの位置にしか存在できません。

Item
Description
Example

My UID

自分のローカルキャラクタの UserID。

Diarkis-Test

Server Count

メッシュネットワーク内の Diarkis サーバーの数は、地面に分割する Grid の数に影響する。

4

Field Size

Field のサイズ。全体の Field のサイズとそれを分割する Grid のサイズを変更される。

4500

Grid Size

1つの Grid サイズ. Field Size と Server Count から算出される。

2250

Leave

Field を離れ、前のシーンに戻る。

MatchMaker

この画面では Diarkis MatchMaker Module を使って IssueTicket を発行し、サーバから他のユーザとのマッチングを待つことができます。マッチングが完了すると、他の Ticket members にメッセージを送ることができます。

Item
Description
Example

TicketType

発行するチケットの種類を指定。 Diarkis Template Serverの基本バージョンでは、チケットタイプ0のみが実装されています。他のチケットタイプを扱うには、サーバ側で何らかの開発が必要です。

0

Issue Ticket

サーバーにMatchMaking の IssueTicket を発行する。

Cancel

IssueTicket をキャンセル。

Status

マッチング状況。

Not Started / Waiting For Match / Complete / Failed

Ticket Owner ID

完了したチケットのオーナー UserID。

Members

完成したチケットのメンバー。

Message

他の Ticket の Member にメッセージを Broadcast する。

Group

Diarkis Group Moduleは、この画面でランダムな Group へのCreaat や Join、他の Group メンバーにメッセージの Broadcast をおこなうことができます。

Item
Description

Group ID

参加している Group ID

Message Button

他の Group メンバーにメッセージを Broadcast する

Direct Message

Diarkis DM Moduleは、この画面で、他のメンバーに直接 Unicast メッセージを送信するために使用することができます。

Item
Description

My UID

自分の UserID

Recipient ID

メッセージを送信するユーザーの UserID

Message Button

Recipient ID で指定したユーザーに Direact Message を送信する。

クラス説明

このクラスは Monobehaviour シングルトンクラスで、ユーザーが Unity Project で Diarkis の機能を使用したい限り有効である必要があります。 Diarkis モジュールオブジェクトを公開するために静的に呼び出すことができます。

使用例:

if (!DiarkisNetworkManager.IsConnected()) // check if the client is not yet connected to Diarkis
{
    DiarkisNetworkManager.Instance.ServerType = Diarkis.ServerType.UDP; // set the protocol to UDP
    DiarkisNetworkManager.Instance.HttpHost = "127.0.0.1:7000"; // set the server address
    DiarkisNetworkManager.Instance.ClientKey = _clientKeyInputField.text; // set the client Key
    DiarkisNetworkManager.Instance.UID = "John Doe"; //set the user ID
    DiarkisNetworkManager.Connect(); // initate Connection to Diarkis
}

インスペクタUIには、エディタからDiarkisのオプションを設定するための様々なオプションが含まれています:

イベント

Diarkis APIは、独自のイベントシステムを使用しています。Diarkisモジュールで特定のアクションが完了すると、関連モジュールによってイベントがトリガーされ、登録されているすべてのコールバックが EventHandler に呼び出されます。各イベントとそのパラメータのシグネチャは、このクラスにあります。

イベント登録の例:

protected override void Start()
{
  DiarkisEventHandler handler = DiarkisNetworkManager.GetEventHandler();
  handler.RegisterCallback(DiarkisEventType.UDPConnect, (System.Action<DiarkisConnectionEventArgs>)((args) => { OnConnect(args); }), this);
}

public void OnConnect(DiarkisConnectionEventArgs args)
{
    if (args.GetStatus() == DiarkisConnectStatus.DCS_Success)
    {
        Logger.Debug("Connection Success");
    }
    else
    {
        Logger.Error("Connection Failed");
    }
}

DiarkisCallbackDispatcher Monobehaviour クラスを使用すると、コードを1行も記述することなく、Editor ユーザーインターフェイスからイベントを登録できます。 また、Event の型シグネチャを覚えておくのにも便利です。

例えば以下の設定は上のコードと同様の動作です。

Logging

Diarkis の Logging システムは、以下の2つのクラスに基づいています:DiarkisLoggerDiarkisLoggingFactory

DiarkisLogger インスタンスは DiarkisLoggerFactory によって作成され、異なるログレベルの情報を記録するために使用されます。これらの Logger は、アプリケーションの実行に関するメッセージ、警告、エラー、その他の関連情報を記録するためのメソッドを提供します。

DiarkisLoggerFactory はネイティブコード内でロガーを作成する役割を担い、Diarkis フレームワーク内の異なるモジュールに Logger インスタンスを提供します。LoggerFactory のコンストラクタで提供されるログ関数は、出力先、ログレベルフィルタリング、およびフォーマットオプションを制御するように設定することができ、開発者は特定のニーズに合わせてロギング動作を調整することができます。

使用例:

    class Program
    {
        static void Main(string[] args)
        {
            var logSeverity = DiarkisLoggerSeverity.Debug;
            var logFileStream = DiarkisUtils.GetFileStreamWriter("./", "diarkis-cs-sample-logs.txt");
            var logAction = new Action<string>((str) =>
            {
                if (str.Contains("\n"))
                {
                    Console.Write(str);
                    logFileStream.Write(str);
                }
                else
                {
                    Console.WriteLine(str);
                    logFileStream.WriteLine(str);
                }
            });
            var loggerFactory = new Diarkis.DiarkisLoggerFactory(logSeverity, logAction);
            DiarkisLogger = loggerFactory.CreateLogger();
            var logger1 = (DiarkisLogger)loggerFactory.CreateLogger("ExampleLogger1");
            var logger2 = (DiarkisLogger)loggerFactory.CreateLogger("ExampleLogger2");
            logger1.Error("this is an error");
            logger2.Debug("this is a Debug log");
            logger2.Verbose("the Debug Log is not displayed because severity level is too high");
            var eventHandler = new DiarkisEventHandler();
            Diarkis.DiarkisInterface diarkis = new Diarkis.DiarkisInterface(loggerFactory, ServerType.UDP, eventHandler);
        }
    }

出力例:

2024-02-01 15:39:32[FAIL][ExampleLogger1]this is an error
2024-02-01 15:39:32[DEBUG][ExampleLogger2]this is a Debug log

注意: 上記のコードは、./diarkis-cs-sample-logs.txtにもファイルを作成し、その出力を登録します。

ログレベルの階層:

public enum DiarkisLoggerSeverity {
  Trace = 0,
  Verbose,
  Debug,
  Info,
  Warning,
  Error,
  Fatal,
  None
}

Logger Manager Inspector

NetworkManager インスペクタには、ロガーを簡単に設定するためのさまざまなフィールドもあります。たとえば、ロガーのカテゴリに応じて異なるログの重大度を設定したり、ゲーム画面にログを表示したりできます。

Diarkis Core Library

Diarkis Core Library は、C++ で作成された DLL です。自動生成される .cs クラスのラッパーファイル Core-wrapped により、C++ のネイティブコードを C# で使用することができます。

Diarkis Module

Diarkis Module は Diarkis C# SDK の一部であり Unity とは独立しており、純粋な C# コンソールアプリケーションで使用できます。

これは実際にはモジュールそのものではなく、すべての Diarkis Module を一度に含むインターフェースとして機能するクラスです。 DiarkisNetworkManager Unity クラスのメンバーですが、基本的な C# コンテキストでも使用できます。 DiarkisInterface は、1つの Diarkis サーバ との接続につき1つ用意する必要があります。MatchMake 用のサーバと TURN 用のサーバを用意する必要がある場合は、DiarkisInterface のインスタンスも 2つ用意する必要があります。

使用例:

  class Program
  {
      static void Main(string[] args)
      {
          var eventHandler = new DiarkisEventHandler(); // Event Handler object (cf: Events)
          var logSeverity = DiarkisLoggerSeverity.Error;
          var logAction = new Action<string>((str) => {Console.WriteLine(str); });
          var loggerFactory = new Diarkis.DiarkisLoggerFactory(logSeverity, logAction); // Logger Factory Object (cf: Logging)

          // DiarkisInterface object is created here (The ServerType is passed as parameter of the constructor UDP/TCP)
          Diarkis.DiarkisInterface diarkis = new Diarkis.DiarkisInterface(loggerFactory, ServerType.UDP, eventHandler);
          diarkis.HttpHost = "192.168.100.12:7000";

          // StartRuntimeThread will initiate the update loop using multiThreading,
          // Since Unity is not a thread safe Engine, it is not recommended to use this function in Unity
          // The recommended behavior is to call diarkis.UpdateComponents(); inside the FixedUpdate function of the
          // DiarkisNetworkManager object
          diarkis.StartRuntimeThread();
          Console.WriteLine("Connecting to " + diarkis.HttpHost);

          // Send the Http Authentication get request to the Http Diarkis server, if the authentication is sucessful
          // the server will reply
          diarkis.sendHttpAuth();

          // note: DiarkisUtils.WaitFor() is using threads will block the main thread until the condition is met.
          // It is not recommended to use it in a Unity Project since it will make the game freeze.
          // Instead it is recommended to use the DiarkisAsync.WaitFor() function which is using the Unity Coroutine mechanism
          if (!DiarkisUtils.WaitFor(() => { return diarkis.IsConnected(); }))
          {
              Console.WriteLine("Connection Timeout");
              return;
          }
          Console.WriteLine("UDP Connection success");

          // listen to the Room Join event (just an example)
          eventHandler.RegisterCallback(Diarkis.DiarkisEventType.RoomJoin,
          (DiarkisRoomJoinEventArgs eventArgs) => { Console.WriteLine("Room Joined!"); });

          // Join a random room
          diarkis.Room.SendJoinRandomRoom(4, 60, 100, true);

          // do any required more actions ...
          return;
      }
  }

このモジュールは、Diarkis サーバとの UDP 接続を作成および管理するために使用され、Room や P2P などの他のいくつかのモジュールはこれに依存しています。

このモジュールは、Diarkis サーバとの TCP 接続を作成および管理するために使用されます。Room や P2P などの他のモジュールは、UDP または TCP のいずれかを使用して設定できますが、一部のモジュールは UDP のみに依存します。

このモジュールは、複数のクライアントが Room に参加し、データ、メッセージ、またはオブジェクト情報を交換できるようにするために使用します。P2P 接続は RoomUDP 接続を使用していることを条件として、グループのメンバと開始することができる。一度に参加できる Room は1つだけで、同じ Room に入室するには同じサーバに接続している必要があります。

このモジュールは、2つのクライアント間の直接ピアツーピア接続の作成と管理に使用します。オプション機能として Room モジュールで使用する。Room に参加したクライアントは P2P 同期を開始し、中間サーバを使用せずにデータを送信できるようになります。

Group モジュールは、複数のクライアントがグループに参加し、メッセージを交換するために使用します。クライアントが同時に参加できる Group 数は無制限で、同じ Group に入室するのに、同じサーバに接続する必要はありません。

このモジュールは一見 Room に似ていますが、いくつかの点で異なります。Field は1つのサーバネットワークに1つしか存在しません。Diarkis のサーバロジックでは、複数の UDP サーバを同じメッシュネットワークの一部として設定することができます。Field はいくつかの Grid に分割され、それぞれのサーバに割り当てられます。各サーバはそれぞれの Grid 内にいるクライアントの情報を伝える役割を担います。 このモジュールは、同時に多数のプレイヤーが参加する可能性のある大規模な環境に最適です。

この Direct Message ( DM )モジュールは、別サーバ間にいるメンバーに直接ユニキャストメッセージを送信するために使用されます。DMRoomGroup とは異なり 同じ部屋に入室せず、 UerID が分かっていれば直接送信できます。

MatchMaker モジュールには、マッチメイキングチケットを発行するための関数とイベントが含まれており、理想的には、マッチメイキング条件はサーバ側で定義されます。クライアントは TicketType を設定して IssueTicket() でチケットを発行するだけです。チケットの発券が完了すると(マッチング条件を満たすプレイヤーが全て見つかると)、 TicketCompleteイベントが発生し、プレイヤーはTicketBroadcastコマンドでマッチングした他のメンバーと通信できるようになります。

Session は、同じメッシュネットワーク内の異なる Diarki サーバ上に同じセッションを存在させることができるという点で、Fieldモジュールと似ています。しかし、その目的は座標データを共有することではなく、限られたプレイヤーグループに対して標準的なデータを交換することです。

カスタムコマンド

Diarkis モジュールを通して送受信されるコマンドのほとんどは 組み込みコマンド です。つまり、その内容はコアライブラリによって把握され、例えば DiarkisRoomJoinEventArgs のような特定の型に解析されます。

しかし、独自のコマンドを開発したい開発者は、サーバ側だけでなくクライアント側にもコマンドを追加する必要があります。このようなコマンドの作成と解析を容易にするために、Diarkisは Puffer というスタンドアロンのバイナリを提供しており、linuxまたはmacのバイナリとして Diarkis Server Template (別のリポジトリ)にあります。

サンプルで使用されているいくつかのペイロードとコマンドを含むjson定義ファイルはCustomCommands.jsonにあります。

カスタムコマンドがサーバ側でどのように定義されるかによりますが、ほとんどの場合、カスタムコマンドの解析は OnResponse または OnPush イベント(UDP または TCP の場合)で行われます。 上で定義したコマンド Zoo の使用例:

        public void OnResponse(DiarkisResponseEventArgs args)
        {
            if (args.GetVersion() == Zoo.VER && args.GetCommand() == Zoo.CMD)
            {
                Zoo zooCommand = new Zoo();
                if (!Zoo.Unpack(args.GetPayload().ToArray()))
                {
                    DiarkisNetworkManager.Instance.Logger.Error("Failed to parse Zoo command");
                    return;
                }
                long lion = zooCommand.Lion;
                byte[] penguins = zooCommand.Penguins;
            }
        }

複数のDiarkisInterfaceインスタンスの使用

DiarkisNetworkManagerは、1つのdiarkis Serverへの単一の接続を使用するように設計されていますが、同時に複数の接続を処理することも可能です。 そのためには、この例のように、DiarkisNetworkManagerオブジェクトを介して、複数の代替DiarkisInterfaceオブジェクトを作成することができます:

        var diarkisLobby = DiarkisNetworkManager.GetDiarkisInterface("Lobby");
        var diarkisGame = DiarkisNetworkManager.GetDiarkisInterface("Game");
        diarkisLobby.EventHandler.RegisterCallback(DiarkisEventType.UDPConnect, new Action<DiarkisConnectionEventArgs>((args) => { Debug.Log("CONNECTED TO LOBBY SERVER."); }));
        diarkisLobby.EventHandler.RegisterCallback(DiarkisEventType.UDPConnect, new Action<DiarkisConnectionEventArgs>((args) => { Debug.Log("CONNECTED TO GAME SERVER."); }));

        DiarkisNetworkManager.Connect("Lobby", DiarkisTransportType.UDP, "LBY");
        DiarkisNetworkManager.Connect("Game", DiarkisTransportType.UDP, "GAME");

非同期コード

イベントは同期的にアクションを実行する方法ですが、開発者は特定のシナリオを非同期的に定義された順序で実行したい場合があります。そのために、DiarkisUtils インターフェースで定義されている WaitFor() 関数があります。

使用例:

class Program
  {
      static void Main(string[] args)
      {
          Diarkis.DiarkisInterface diarkis = new Diarkis.DiarkisInterface(loggerFactory, ServerType.UDP, eventHandler);
          diarkis.HttpHost = "192.168.100.12:7000";
          diarkis.StartRuntimeThread();
          Console.WriteLine("Connecting to " + diarkis.HttpHost);
          diarkis.sendHttpAuth();
          if (!DiarkisUtils.WaitFor(() => { return diarkis.IsConnected(); }))
          {
              Console.WriteLine("Connection Timeout");
              return;
          }
          Console.WriteLine("UDP Connection success");
          Console.WriteLine("Joining a Room...");
          diarkis.Room.SendJoinRandomRoom(4, 60, 100, true);
          if (!DiarkisUtils.WaitFor(() => { return diarkis.Room.ID != ""; }))
          {
              Console.WriteLine("Room Join Timeout");
              return;
          }
          Console.WriteLine("Room Joined!");
          return;
      }
  }

注意:DiarkisUtils.WaitFor()Threading.Sleep() 関数を使っています。 これは、条件が満たされるまでメインスレッドをブロックしていることを意味します。 代わりに、 DiarkisAsyncインターフェイスのDiarkisAsync.WaitFor()バージョンを使用することをお勧めします。このインターフェイスでは、 Threads の代わりにUnityの Coroutine メカニズムを使用します。

Unity 非同期コードの使用例:

void Start()
{
    StartCoroutine(ConnectAndJoinRoomAsync())
}

public IEnumerator ConnectAndJoinRoomAsync()
{
    DiarkisNetworkManager.Connect();
    DiarkisAsyncResult res = new DiarkisAsyncResult();
    yield return DiarkisAsync.WaitFor(() =>
    {
        return IsConnected();
    }, res);
    if (!res.completed)
    {
        if (Logger != null)
        {
            Logger.Error("Connection Time Out");
        }
        yield break;
    }

    Logger.Debug("Connection Success");
    Logger.Debug("Joining Random Room...");
    DiarkisNetworkManager.GetRoom().SendJoinRandomRoom(4, 60, 100, true);
    yield return DiarkisAsync.WaitFor(() =>
    {
        return DiarkisNetworkManager.GetRoom().ID != "";
    }, res);
    if (!res.completed)
    {
        if (Logger != null)
        {
            Logger.Error("Room Join Time Out");
        }
        yield break;
    }
    Logger.Debug("Room succesfully joined");
    yield return null;
}

Diarkis イベントを非同期にキャッチする

Diarkisライブラリは、イベントセクションで説明したように、コールバック関数を使用してイベントを同期的に呼び出すように設計されています。しかし、前述の関数とイベントコールバックを組み合わせることで、イベントコールバックを非同期のコンテキストで使用することができます。

以下は、イベントコールバックを使って非同期にメンバーの入室を待つ関数の例です:

        void Start()
        {
            StartCoroutine(WaitForRoomMemberJoin())
        }

        IEnumerator WaitForRoomMemberJoin()
        {
            DiarkisAsyncResult res = new DiarkisAsyncResult();
            DiarkisPayloadEventArgs eventArgs = null;
            var callback = (Action<DiarkisPayloadEventArgs>)((args) => { eventArgs = args; });
            DiarkisNetworkManager.GetEventHandler()?.RegisterCallback(Diarkis.DiarkisEventType.RoomMemberJoin, callback, this);
            yield return DiarkisAsync.WaitFor(() =>
            {
                return eventArgs != null;
            }, res);

            DiarkisNetworkManager.GetEventHandler()?.UnregisterCallback(callback);
            if (res.completed)
            {
                // callback triggered
            }
            else
            {
                //callback trigger timeout
            }
            yield return null;
        }

カスタムアロケータ

Diarkis Native Libraryのコード全体で使用するアロケータサイズを任意に設定することができます。そのために、静的関数 SetCustomAllocatorSizeSetCustomAllocator が用意されています。

このサイズは使用可能なメモリー・サイズを超えてはならず、そうでない場合は例外がスローされます。

以下の例では、アロケーターのサイズを16MBに設定しています。通常、Diarkisライブラリーは500Kb以上使用することはありませんが、少なくとも4Mbは使用することをお勧めします。 使用例:

  class Program
  {
      static void Main(string[] args)
      {
          //Parameters are the Size of the Buffer, and the alignment.
          ICustomAllocator _originalAllocator = DiarkisLib.SetCustomAllocatorSize(1024 * 1024 * 16, 16);

          // code using Diarkis ...

          // When Diarkis resources are done to be used and have been disposed, the Allocator can be safely reset
          DiarkisLib.SetCustomAllocator(_originalAllocator);
          return;
      }
  }

メモリー安全性に関する注意事項

Diarkis C# SDKは、もともとC++で作成され、ネイティブライブラリにコンパイルされたコア Diarkis Library に基づいています。自動生成される .cs クラスのラッパーファイルにより、C++ のネイティブコードを C# で使用することができます。しかし、 C++C# は明らかに同じ言語ではなく、最も重要な違いはメモリの管理方法です。 C# はヒープ管理がガーベジコレクタ (GC) によって処理されるため、「メモリセーフ」です。 C++ は GC を持たないので、データの割り当て/解放を管理するのは開発者の責任です。

そのため、Native Diarkis Library の各ラップクラスは C# 型の IDisposable から派生しています。これらのオブジェクトは Garbage Collector にデータを気にしないように指示する機能を持っており、 Dispose() 関数を使用することで、管理されていないリソースを開発者が任意に解放することができます。

いったん Dispose() 関数が呼び出されると、このオブジェクトに割り当てられたアンマネージドリソースに依存するすべてのコードは Memory ExceptionUnity Editor のクラッシュ、Memory Leaks を引き起こす可能性があることを理解しておくことが重要です。 このような問題が発生した場合、リソースの解放が早すぎたり、使用時期が遅すぎたりした可能性があります

iOSでのビルド

iOSでビルドする場合、まずPlayer Settingsで特定の値を設定することが重要です。Optimization セクションで、Managed Stripping Levelminimalに設定します。

iOSでビルドする場合、Diarkis Librariesが正しく実行されるように若干の修正が必要な場合があります。 Unityエディタでビルドボタンを押すと、Unityによってxcodeプロジェクトフォルダが生成されます。 xcodeプロジェクトを開き、Unity-iPhoneターゲットを選択し、Generalタブを開きます。 次に、左側のパネルにあるプロジェクトに2つのDiarkisランタイムライブラリファイルを追加する必要があり、それらは Libraries\Diarkis\Libraries\iOS フォルダにあります。 次に、これらのファイルをFrameworks, Libraries, and Embedded Contentリストに追加します。 これは、アプリをインストールするときにiOSデバイスにライブラリがコピーされるようにするために必要です。

visionOS と visionOS-Simulator でのビルド

visionOSでのビルドはiOSでのビルドと似ていますが、xcode.˶でいくつかの追加ステップが必要です。 最初に知っておくべきことは、Unityのビルドウィンドウで、プラットフォームをvisionOSかvisionOS-Simulatorの間で切り替えることができるということです。

また、シミュレータでビルドするか、実際のvisionOSデバイスでビルドするかによって、エディタでライブラリのパラメータを変更する必要があります。 例えば、VisionOS-Simulator-arm64でビルドしたい場合は、Packages>Diarkis Plugin Sample>Core>Libraries>visionOS-Simulator-arm64 フォルダで2つのライブラリを選択し、プラットフォームをvisionOSに設定して、競合するライブラリを無効にする必要があります。

ビルドが完了したら、xcodeのプロジェクトファイルをxcodeで開きます(visionOSをサポートするにはバージョン15.2以上が必要です)。そして、iOSビルドと同様に、ターゲット・プラットフォームに対応するライブラリを左パネルのプロジェクトに追加します。

Add to targetに必ずチェックを入れます: Unity-visionOS`にチェックを入れてください。

次に、Unity-VisionOS > General > Frameworks, Libraries, and Embedded Contentで、2つのdiarkisライブラリをEmbed & Signに設定します。

(このステップはシミュレータに特有のものです)。 Unity-VisionsOS > Build Settings > Linking - General で、Other Linker Flags に値 -ld64 を追加します。

これでリンカが正しく設定され、アプリをvisionOS用にビルドできるようになりました。

難読化

難読化ツールはDiarkisで安全に使用することができます。例として、Beebyte Obfuscator from the Unity Asset StoreはDiarkisサンプルの難読化バージョンをビルドするために使用されています。バイナリファイルにはアプリケーションのロジックを隠すアセンブリが含まれており、ハッカーがソースコードをリバースエンジニアリングすることを困難にします。

Beebyte Obfuscator を使用するには、まずライセンスを購入し、Window > Package Manager ウィンドウからダウンロードしてプロジェクトにインポートする必要があります。

パッケージがインポートされると、Assets/Editor/Beebyte/Obfuscator/ObfuscsatorOptions.key に settings prefab が作成されます。 この設定を変更することで、難読化をより積極的にしたり、そうでなかったりすることができます。 デフォルト設定で問題なく動作するはずです。

そして、File > Build Settings ウィンドウからプロジェクトをビルドし、Clean Build オプションを使用して、難読化設定が各ビルド間で適用されていることを確認します。

最終更新