すべてを統合する - パーティ入門 - (Unreal Engine モジュール)
注釈:本資料はAI技術を用いて翻訳されています。
UIを接続してパーティメンバーの表示、脱退、招待送信、キック、昇格を行う
-
PartyWidgetEntry_StarterクラスのCPPファイルを開き、SetPartyMember()関数に以下のコードを追加します。これにより、パーティメンバーの表示名とアバターが表示されます。void UPartyWidgetEntry_Starter::SetPartyMember(const FUserOnlineAccountAccelByte& PartyMember, const bool bIsLeader)
{
W_PartyMember->SetNetId(PartyMember.GetUserId());
// Display party member information.
Ws_PartyMemberState->SetActiveWidget(W_PartyMemberPanel);
// Set display name.
if (PartyMember.GetDisplayName().IsEmpty())
{
const FUniqueNetIdAccelByteUserRef MemberABId = StaticCastSharedRef<const FUniqueNetIdAccelByteUser>(PartyMember.GetUserId());
W_PartyMember->SetUsername(FText::FromString(UTutorialModuleOnlineUtility::GetUserDefaultDisplayName(MemberABId.Get())));
}
else
{
W_PartyMember->SetUsername(FText::FromString(PartyMember.GetDisplayName()));
}
// Set avatar
FString AvatarURL;
PartyMember.GetUserAttribute(ACCELBYTE_ACCOUNT_GAME_AVATAR_URL, AvatarURL);
W_PartyMember->SetAvatar(AvatarURL);
// Set color tint.
const FLinearColor MemberColor = bIsLeader ? PartyLeaderColor : PartyMemberColor;
SetPartyMemberColor(MemberColor);
W_PartyMember->SetTextColor(MemberColor);
W_PartyMember->SetAvatarTint(AvatarURL.IsEmpty() ? MemberColor : FLinearColor::White);
// Set cached party member data as friend data.
// Will be used to open player action menu widget.
if (!CachedFriendData)
{
CachedFriendData = NewObject<UFriendData>();
}
CachedFriendData->UserId = PartyMember.GetUserId();
CachedFriendData->DisplayName = PartyMember.GetDisplayName();
CachedFriendData->AvatarURL = AvatarURL;
W_PartyMember->ActivateWidget();
} -
次に、
PartyWidget_StarterクラスのCPPファイルを開き、DisplayParty()関数に以下のコードを追加します。これにより、パーティメンバー情報をクエリして表示します。void UPartyWidget_Starter::DisplayParty()
{
// Show loading.
Btn_Leave->SetVisibility(ESlateVisibility::Collapsed);
Ws_Party->SetWidgetState(EAccelByteWarsWidgetSwitcherState::Loading);
// Collect party member user IDs.
const FUniqueNetIdPtr UserId = PartyOnlineSession->GetLocalPlayerUniqueNetId(GetOwningPlayer());
TArray<FUniqueNetIdRef> PartyMemberUserIds = PartyOnlineSession->GetPartyMembers();
// If not in any party, then only include player user ID to query its information.
if (PartyMemberUserIds.IsEmpty())
{
PartyMemberUserIds.Add(UserId.ToSharedRef());
}
// Query and display party member information.
if (UStartupSubsystem* StartupSubsystem = GetWorld()->GetGameInstance()->GetSubsystem<UStartupSubsystem>())
{
StartupSubsystem->QueryUserInfo(
PartyOnlineSession->GetLocalUserNumFromPlayerController(GetOwningPlayer()),
PartyMemberUserIds,
FOnQueryUsersInfoCompleteDelegate::CreateWeakLambda(this, [this](
const FOnlineError& Error,
const TArray<TSharedPtr<FUserOnlineAccountAccelByte>> UsersInfo)
{
// If party members are changed during query, then re-query the party members' information.
const bool bIsInParty = !PartyOnlineSession->GetPartyMembers().IsEmpty();
if (bIsInParty)
{
TArray<FString> QueriedUserIds{};
for (const TSharedPtr<FUserOnlineAccountAccelByte>& UserInfo : UsersInfo)
{
if (const FUniqueNetIdAccelByteUserPtr ABUserId = UTutorialModuleOnlineUtility::GetAccelByteUserId(UserInfo->GetUserId()))
{
QueriedUserIds.Add(ABUserId->GetAccelByteId());
}
}
for (const FUniqueNetIdPtr PartyMember : PartyOnlineSession->GetPartyMembers())
{
const FUniqueNetIdAccelByteUserPtr ABUserId = UTutorialModuleOnlineUtility::GetAccelByteUserId(PartyMember);
if (ABUserId->IsValid())
{
continue;
}
if (!QueriedUserIds.Contains(ABUserId->GetAccelByteId()))
{
DisplayParty();
return;
}
}
}
// Request failed.
if (!Error.bSucceeded)
{
Ws_Party->SetWidgetState(EAccelByteWarsWidgetSwitcherState::Error);
return;
}
// Clean up last party member list.
Ws_Party->SetWidgetState(EAccelByteWarsWidgetSwitcherState::Not_Empty);
Hb_Party->ClearChildren();
Btn_Leave->SetVisibility(ESlateVisibility::Visible);
// Display party members.
for (int32 i = 0; i < MaxPartyMembers; i++)
{
if (i < UsersInfo.Num() && !UsersInfo[i])
{
continue;
}
const TWeakObjectPtr<PARTY_WIDGET_ENTRY_CLASS> PartyMemberEntry =
MakeWeakObjectPtr<PARTY_WIDGET_ENTRY_CLASS>(
CreateWidget<PARTY_WIDGET_ENTRY_CLASS>(this, PartyWidgetEntryClass.Get()));
Hb_Party->AddChild(PartyMemberEntry.Get());
// Display party member information.
if (i < UsersInfo.Num())
{
/* Mark party member as leader if valid.
* If not in any party, then assume the player as the leader.*/
PartyMemberEntry->SetPartyMember(
*UsersInfo[i],
PartyOnlineSession->IsPartyLeader(UsersInfo[i]->GetUserId()) || !bIsInParty);
}
// Display button to add more party members.
else
{
PartyMemberEntry->ResetPartyMember();
}
}
}));
}
} -
同じファイルで、
OnLeaveButtonClicked()関数に以下のコードを追加します。これにより、脱退ボタンがクリックされたときにパーティから脱退するトリガーが実行されます。void UPartyWidget_Starter::OnLeaveButtonClicked()
{
// Leave current party.
PartyOnlineSession->LeaveParty(PartyOnlineSession->GetLocalUserNumFromPlayerController(GetOwningPlayer()));
DeactivateWidget();
} -
同じファイルで、
NativeOnActivated()関数に以下のコードを追加します。この関数は、パーティイベントをリッスンして、UI上に表示されるパーティメンバーを更新します。void UPartyWidget_Starter::NativeOnActivated()
{
Super::NativeOnActivated();
Btn_Leave->OnClicked().Clear();
Btn_Leave->OnClicked().AddUObject(this, &ThisClass::OnLeaveButtonClicked);
// Update the displayed party members on any changes.
PartyOnlineSession->GetOnCreatePartyCompleteDelegates()->AddWeakLambda(this, [this](FName SessionName, bool bWasSuccessful)
{
DisplayParty();
});
PartyOnlineSession->GetOnLeavePartyCompleteDelegates()->AddWeakLambda(this, [this](FName SessionName, bool bWasSuccessful)
{
DisplayParty();
});
// ...
PartyOnlineSession->GetOnPartyMemberJoinedDelegates()->AddWeakLambda(this, [this](FName SessionName, const FUniqueNetId& Participant)
{
DisplayParty();
});
PartyOnlineSession->GetOnPartyMemberLeftDelegates()->AddWeakLambda(this, [this](FName SessionName, const FUniqueNetId& Participant, EOnSessionParticipantLeftReason Reason)
{
DisplayParty();
});
// ...
PartyOnlineSession->GetOnPartySessionUpdateReceivedDelegates()->AddWeakLambda(this, [this](FName SessionName)
{
DisplayParty();
});
DisplayParty();
} -
同じファイルで、
NativeOnDeactivated()関数に以下のコードを追加します。これにより、パーティウィジェットが非アクティブ化された後、パーティイベントのバインドが解除されます。void UPartyWidget_Starter::NativeOnDeactivated()
{
Btn_Leave->OnClicked().Clear();
// Clear online delegates.
PartyOnlineSession->GetOnCreatePartyCompleteDelegates()->RemoveAll(this);
PartyOnlineSession->GetOnLeavePartyCompleteDelegates()->RemoveAll(this);
// ...
PartyOnlineSession->GetOnPartyMemberJoinedDelegates()->RemoveAll(this);
PartyOnlineSession->GetOnPartyMemberLeftDelegates()->RemoveAll(this);
// ...
PartyOnlineSession->GetOnPartySessionUpdateReceivedDelegates()->RemoveAll(this);
Super::NativeOnDeactivated();
} -
UI上にパーティメンバーを表示するコードが完成しました。次に、パーティ関連のアクションを実行するためにいくつかの関数を呼び出す必要があります。
PartyOnlineSession_StarterクラスのCPPファイルを開き、それぞれの事前定義された関数に以下のコードを追加します。これは、パーティアクションボタンがクリックされたときに、それぞれのパーティアクションを呼び出すものです。これらのアクションボタンは、このモジュールのパーティメニューの追加チュートリアルで説明されている生成されたボタンです。void UPartyOnlineSession_Starter::OnInviteToPartyButtonClicked(const int32 LocalUserNum, const FUniqueNetIdPtr& Invitee)
{
// Disable the button to avoid spamming.
if (InviteToPartyButtonMetadata)
{
if (UAccelByteWarsButtonBase* Button =
Cast<UAccelByteWarsButtonBase>(InviteToPartyButtonMetadata->GenerateWidgetRef))
{
Button->SetIsInteractionEnabled(false);
}
}
SendPartyInvite(LocalUserNum, Invitee);
}void UPartyOnlineSession_Starter::OnKickPlayerFromPartyButtonClicked(const int32 LocalUserNum, const FUniqueNetIdPtr& KickedPlayer)
{
// Disable the button to avoid spamming.
if (KickPlayerFromPartyButtonMetadata)
{
if (UAccelByteWarsButtonBase* Button =
Cast<UAccelByteWarsButtonBase>(KickPlayerFromPartyButtonMetadata->GenerateWidgetRef))
{
Button->SetIsInteractionEnabled(false);
}
}
KickPlayerFromParty(LocalUserNum, KickedPlayer);
}void UPartyOnlineSession_Starter::OnPromotePartyLeaderButtonClicked(const int32 LocalUserNum, const FUniqueNetIdPtr& NewLeader)
{
// Disable the button to avoid spamming.
if (PromotePartyLeaderButtonMetadata)
{
if (UAccelByteWarsButtonBase* Button =
Cast<UAccelByteWarsButtonBase>(PromotePartyLeaderButtonMetadata->GenerateWidgetRef))
{
Button->SetIsInteractionEnabled(false);
}
}
PromotePartyLeader(LocalUserNum, NewLeader);
}
リソース
-
このチュートリアルセクションで使用されているファイルは、Unreal Byte Wars GitHubリポジトリで入手できます。