メインコンテンツまでスキップ

すべてをまとめる - プレゼンスの基本 - (Unreal Engine モジュール)

Last updated on February 4, 2026

注釈:本資料はAI技術を用いて翻訳されています。

プレゼンスを表示するためのUIの接続

このチュートリアルでは、PresenceEssentialsSubsystem_Starter で作成した実装をプレゼンスウィジェットに接続します。

  1. PresenceWidget_Starter クラスの CPP ファイルを開き、RefreshPresence() 関数を以下のコードに置き換えます。このコードは、プレイヤーのプレゼンスを取得し、画面に表示します。

    void UPresenceWidget_Starter::RefreshPresence(bool bForceQueryPresence)
    {
    const FUniqueNetIdAccelByteUserPtr PresenceUserABId = StaticCastSharedPtr<const FUniqueNetIdAccelByteUser>(PresenceUserId);
    if (!PresenceUserABId)
    {
    UE_LOG_PRESENCEESSENTIALS(Warning, TEXT("Unable to get presence to be displayed on the widget. User Id is not valid."));
    return;
    }

    const FString UserABId = PresenceUserABId->GetAccelByteId();
    Tb_Presence->SetVisibility(ESlateVisibility::Collapsed);
    Th_Loader->SetVisibility(ESlateVisibility::Visible);

    PresenceEssentialsSubsystem->GetPresence(
    PresenceUserABId,
    bForceQueryPresence,
    FOnPresenceTaskComplete::CreateWeakLambda(this, [this, UserABId](const bool bWasSuccessful, const TSharedPtr<FOnlineUserPresenceAccelByte> Presence)
    {
    // Abort if the widget is being destroyed.
    if (!IsValid(this) || IsUnreachable())
    {
    return;
    }

    FString PresenceStr;

    // Set offline if presence is invalid.
    if (!bWasSuccessful || !Presence)
    {
    PresenceStr = TEXT_PRESENCE_OFFLINE.ToString();
    }
    // Set valid presence.
    else
    {
    // Set online and status.
    if (Presence->bIsOnline)
    {
    PresenceStr = TEXT_PRESENCE_ONLINE.ToString();

    // Presence status is only be displayed if the presence widget is not displayed in a list entry.
    if (!ParentListView &&
    !Presence->Status.StatusStr.IsEmpty() &&
    !Presence->Status.StatusStr.Equals(FString("nil"), ESearchCase::IgnoreCase))
    {
    PresenceStr += FString("\n") + Presence->Status.StatusStr;
    }
    }
    // Set last seen.
    else
    {
    PresenceStr = GetLastOnline(Presence->LastOnline);
    }
    }

    // Display presence.
    Th_Loader->SetVisibility(ESlateVisibility::Collapsed);
    Tb_Presence->SetAutoWrapText(ParentListView == nullptr);
    Tb_Presence->SetScrollingEnabled(ParentListView != nullptr);
    Tb_Presence->SetText(FText::FromString(PresenceStr));
    Tb_Presence->SetVisibility(ESlateVisibility::Visible);

    // Refresh list if any.
    if (ParentListView)
    {
    ParentListView->RequestRefresh();
    }

    UE_LOG_PRESENCEESSENTIALS(Log, TEXT("Presence widget is updated for user: %s"), *UserABId);
    }
    ));
    }
  2. 次に、PresenceWidget_Starter クラスのヘッダーファイルを開き、以下の関数を宣言します。

    protected:
    // ...
    void OnPresenceUpdated(const FUniqueNetId& UserId, const TSharedRef<FOnlineUserPresence>& Presence);
    protected:
    // ...
    void OnBulkQueryPresenceComplete(const bool bWasSuccessful, const FUserIDPresenceMap& Presences);
  3. 次に、PresenceWidget_Starter クラスの CPP ファイルに戻り、OnPresenceUpdated() 関数を定義します。この関数は、プレゼンスの更新を受信したときにウィジェットを更新します。

    void UPresenceWidget_Starter::OnPresenceUpdated(const FUniqueNetId& UserId, const TSharedRef<FOnlineUserPresence>& Presence)
    {
    const FUniqueNetIdAccelByteUserPtr PresenceUserABId = StaticCastSharedPtr<const FUniqueNetIdAccelByteUser>(PresenceUserId);
    if (!PresenceUserABId)
    {
    return;
    }

    if (PresenceUserABId && UserId == PresenceUserId.ToSharedRef().Get())
    {
    UE_LOG_PRESENCEESSENTIALS(Log, TEXT("Received presence update for user: %s. Updating the presence widget."), *PresenceUserABId->GetAccelByteId());
    RefreshPresence();
    }
    }
  4. 同じファイルで、OnBulkQueryPresenceComplete() 関数を定義します。同様に、この関数は、プレゼンスの一括クエリを受信したときにウィジェットを更新します。このイベントは、フレンドリストまたはブロックされたプレイヤーリストが更新されたときに呼び出されます。

    void UPresenceWidget_Starter::OnBulkQueryPresenceComplete(const bool bWasSuccessful, const FUserIDPresenceMap& Presences)
    {
    const FUniqueNetIdAccelByteUserPtr PresenceUserABId = StaticCastSharedPtr<const FUniqueNetIdAccelByteUser>(PresenceUserId);
    if (!PresenceUserABId)
    {
    return;
    }

    if (bWasSuccessful && Presences.Contains(PresenceUserABId->GetAccelByteId()))
    {
    UE_LOG_PRESENCEESSENTIALS(Log, TEXT("Received bulk presence update for user: %s. Updating the presence widget."), *PresenceUserABId->GetAccelByteId());
    RefreshPresence();
    }
    }
  5. 次に、作成した関数をバインドしてコードを完成させます。これを行うには、事前定義された OnSetupPresenceComplete() 関数を以下のコードに置き換えます。

    void UPresenceWidget_Starter::OnSetupPresenceComplete()
    {
    // Bind presence events.
    if (!PresenceEssentialsSubsystem->GetOnBulkQueryPresenceCompleteDelegates()->IsBoundToObject(this))
    {
    PresenceEssentialsSubsystem->GetOnPresenceReceivedDelegates()->AddUObject(this, &ThisClass::OnPresenceUpdated);
    PresenceEssentialsSubsystem->GetOnBulkQueryPresenceCompleteDelegates()->AddUObject(this, &ThisClass::OnBulkQueryPresenceComplete);
    }

    // Get and display presence.
    const AAccelByteWarsGameState* GameState = Cast<AAccelByteWarsGameState>(GetWorld()->GetGameState());
    const AAccelByteWarsInGameGameState* InGameGameState = Cast<AAccelByteWarsInGameGameState>(GameState);
    bool bForceQueryPresence = InGameGameState != nullptr;

    RefreshPresence(bForceQueryPresence);
    }
  6. 最後に、ウィジェットが破棄されるときにこれらのイベントをアンバインドします。これを行うには、事前定義された NativeDestruct() 関数を以下のコードに置き換えます。

    void UPresenceWidget_Starter::NativeDestruct()
    {
    // Clear cache.
    PresenceUserId = nullptr;
    ParentListView = nullptr;

    // Unbind presence events.
    PresenceEssentialsSubsystem->GetOnPresenceReceivedDelegates()->RemoveAll(this);
    PresenceEssentialsSubsystem->GetOnBulkQueryPresenceCompleteDelegates()->RemoveAll(this);

    Super::NativeDestruct();
    }

リソース