Diarkis Module のカスタマイズ

Diarkis クライアントではコールバック関数をカスタマイズすることで Diarkis サーバーに接続完了した時や Room に参加した時など様々なイベントに合わせて任意の処理を実行することができます。

ここでは、クイックスタート で作成した TutorialSubsystem クラスを変更し、ConnectUdp 関数から ConnectUdpAsync 関数に変更し、コールバック関数を使って接続状態を判断するように変更する方法について解説します。

ConnectUdpAsync 関数への変更

ConnectUdp 関数を実行するとサーバーに接続できない場合、タイムアウトするまで動作が停止します。そこで応答性を高めるために ConnectUdpAsync 関数に変更します。

// TutorialSubsystem.cpp
	
	...
	// UDP サーバに接続
	// Connect to the UDP server
	UE_LOG(LogTemp, Log, TEXT("Connecting to the UDP server..."));
	bool result = DiarkisInterfaceInstance->ConnectUdpAsync(endpoint);

また、実際にサーバーへの接続処理が完了する前に ConnectUdpAsync 関数の次の処理が実行されるため、下記のログの処理を削除します。

UE_LOG(LogTemp, Log, TEXT("Connected to the UDP server")); // <-- 削除

コールバック関数の実装

  1. DiarkisUdpBase クラスを継承したクラスを作成します。

    // TutorialSubsystem.h
    
    ...
    #include "DiarkisUdpBase.h"
    
    class DiarkisUdpTutorial;
    ...
    // Diarkis Module の Udp 機能をアプリ側でカスタマイズするために DiarkisUdpBase を継承したクラスを実装します。
    // Implement a class that inherits from DiarkisUdpBase to customize the Udp functionality of the Diarkis Module on the application side.
    class DiarkisUdpTutorial : public Diarkis::DiarkisUdpBase
    {
    private:
        void OnConnect(const DiarkisConnectionEventArgs& args) override;
    };
    // TutorialSubsystem.cpp
    
    ...
    void DiarkisUdpTutorial::OnConnect(const DiarkisConnectionEventArgs& args)
    {
    	if (args.GetStatus() == Diarkis::DiarkisConnectStatus::DCS_Timeout)
      {
    		UE_LOG(LogTemp, Error, TEXT("Timeout occurred while connecting to the UDP server"));
    		return;
    	}
        UE_LOG(LogTemp, Log, TEXT("Connected to the UDP server"));
    }
  2. DiarkisIntefaceBase クラスを継承したクラスを作成します。

    // TutorialSubsystem.h
     
    ...
    #include "DiarkisUdpBase.h"
    #include "DiarkisInterfaceBase.h"
    ...
    class DiarkisUdpTutorial;
    class DiarkisInterfaceTutorial;
    ...
    // DiarkisInterface が内部で管理する各機能のモジュールをアプリ固有のものに置き換えるために DiarkisInterfaceBase を継承したクラスを実装します。
    // Implement a class that inherits from DiarkisInterfaceBase to replace each functional module managed internally by DiarkisInterface with application-specific ones.
    class DiarkisInterfaceTutorial : public Diarkis::DiarkisInterfaceBase
    {
    public:
        DiarkisInterfaceTutorial(const std::string& uid) : Diarkis::DiarkisInterfaceBase(uid) {};
    
        bool SetupUdp() override;
    };
    // TutorialSubsystem.cpp
    
    bool DiarkisInterfaceTutorial::SetupUdp()
    {
        // アプリ側でカスタマイズした DiarkisUdpTutorial クラスを作成します
        // Create a DiarkisUdpTutorial class customized on the application side
        if (udpBase_ == nullptr)
        {
            udpBase_ = Diarkis::DiarkisAllocShared<DiarkisUdpTutorial>();
        }
    
        DiarkisInterfaceBase::SetupUdp();
    
        return true;
    }
  3. DiarkisInterfaceBase クラスを作成していた部分を書き換えます。

    // TutorialSubsystem.h
    
    UCLASS()
    class TUTORIAL_API UTutorialSubsystem : public UGameInstanceSubsystem
    {
    ...
    private:
        std::shared_ptr<DiarkisInterfaceTutorial> DiarkisInterfaceInstance;
    // TutorialSubsystem.cpp 
    
    void UTutorialSubsystem::Initialize(FSubsystemCollectionBase& Collection)
    {
        ...
        // DiarkisInterfaceインスタンスの作成
        // Create DiarkisInterface instance
        DiarkisInterfaceInstance = Diarkis::DiarkisAllocShared<DiarkisInterfaceTutorial>("AAAA");

最終的なコードは下記のようになります。

処理を追加した後は、再度ビルドし、ゲーム起動時に "Connected to the UDP server" というログが表示され、ゲーム終了時に "Disconnected from the UDP server." というログが表示されることを確認します。

ここまでで UE Plugin を使い、Diarkis サーバーへの非同期接続とコールバック関数を使って接続状態を判断することができました。

今回は、コールバック関数の中でスレッドセーフな UE_LOG 関数しか実行していませんが、実際のアプリケーションではコールバック内で様々な処理を実行することが想定されます。しかし、コールバックは Diarkis が管理するイベントスレッドで発火され、ゲームスレッドで実行されるわけではないため、このコールバック内で SpawnActor 関数の実行などの UE 関連の機能を使用することができません。 これらの課題に対応するために DiarkisPluginSample では様々なイベント処理が実装されています。

次のページで DiarkisPluginSample に含まれる DiarkisExtension プラグインを使用して、ゲームスレッドでコールバック関数を実行する方法を説明します。

最終更新

役に立ちましたか?