From c8ebb6b93607b7f14afabd407a0df5da6c0e17b6 Mon Sep 17 00:00:00 2001 From: Nicholas Nakano <nicksnak01@gmail.com> Date: Wed, 24 Aug 2022 13:07:20 -0700 Subject: [PATCH] Added Voice Chat code to Gamemode and Controller --- .../Private/ARNOPlayerController.cpp | 46 +++++++++++++++ .../arnocMain/Public/ARNOPlayerController.h | 15 ++++- Source/arnocMain/arnocMainGameModeBase.cpp | 56 +++++++++++++++++++ Source/arnocMain/arnocMainGameModeBase.h | 9 +++ 4 files changed, 125 insertions(+), 1 deletion(-) diff --git a/Source/arnocMain/Private/ARNOPlayerController.cpp b/Source/arnocMain/Private/ARNOPlayerController.cpp index 7c145d7..e0b32dc 100644 --- a/Source/arnocMain/Private/ARNOPlayerController.cpp +++ b/Source/arnocMain/Private/ARNOPlayerController.cpp @@ -2,4 +2,50 @@ #include "ARNOPlayerController.h" +#include <ArnoEOSSubsystem.h> +void AARNOPlayerController::OnLoginComplete(const FString& PlayerName, const FVoiceChatResult& Result) +{ + if (Result.IsSuccess()) + { + FString DeviceName = VoiceChatUser->GetDefaultInputDeviceInfo().DisplayName; + UE_LOG(LogTemp, Display, TEXT("VOIP Initialized: Using %s as input device."), *DeviceName); + } +} + +void AARNOPlayerController::DoLogin() +{ + UArnoEOSSubsystem* Subsystem = GetGameInstance()->GetSubsystem<UArnoEOSSubsystem>(); + VoiceChatUser = Subsystem->VoiceChatInitialize(); +} + +void AARNOPlayerController::BeginDestroy() +{ + UArnoEOSSubsystem* Subsystem = GetGameInstance()->GetSubsystem<UArnoEOSSubsystem>(); + if (Subsystem != nullptr) + { + Subsystem->VoiceChatDeinitialize(VoiceChatUser); + } + Super::BeginDestroy(); +} + +void AARNOPlayerController::JoinVoiceChannel_Implementation(const FString& InChannelName, + const FString& InChannelCredentials) +{ + if (VoiceChatUser == nullptr) + { + return; + } + + VoiceChatUser->JoinChannel( + InChannelName, + InChannelCredentials, + EVoiceChatChannelType::Positional, + FOnVoiceChatChannelJoinCompleteDelegate::CreateLambda([](const FString& ChannelName, const FVoiceChatResult& Result) + { + if (Result.IsSuccess()) + { + UE_LOG(LogTemp, Display, TEXT("User has joined Voice Chat.")); + } + })); +} diff --git a/Source/arnocMain/Public/ARNOPlayerController.h b/Source/arnocMain/Public/ARNOPlayerController.h index f20356c..b51e3d6 100644 --- a/Source/arnocMain/Public/ARNOPlayerController.h +++ b/Source/arnocMain/Public/ARNOPlayerController.h @@ -4,6 +4,7 @@ #include "CoreMinimal.h" #include "GameFramework/PlayerController.h" +#include "VoiceChat.h" #include "ARNOPlayerController.generated.h" /** @@ -13,5 +14,17 @@ UCLASS() class ARNOCMAIN_API AARNOPlayerController : public APlayerController { GENERATED_BODY() - + + IVoiceChatUser* VoiceChatUser; + + void OnLoginComplete(const FString& PlayerName, const FVoiceChatResult& Result); + + UFUNCTION(BluePrintCallable) + void DoLogin(); + +public: + UFUNCTION(Client, Reliable) + void JoinVoiceChannel(const FString& InChannelName, const FString& InChannelCredentials); + + virtual void BeginDestroy() override; }; diff --git a/Source/arnocMain/arnocMainGameModeBase.cpp b/Source/arnocMain/arnocMainGameModeBase.cpp index d6b4459..5867ee9 100644 --- a/Source/arnocMain/arnocMainGameModeBase.cpp +++ b/Source/arnocMain/arnocMainGameModeBase.cpp @@ -51,6 +51,45 @@ void AarnocMainGameModeBase::PostLogin(APlayerController* NewPlayer) } Super::PostLogin(NewPlayer); + + // Voice Chat Channel Initialization: + if (NewPlayer->IsLocalPlayerController()) + { + return; + } + + AARNOPlayerController* CustomPC = Cast<AARNOPlayerController>(NewPlayer); + if (!IsValid(CustomPC)) + { + // Not the correct type of player controller. + return; + } + UNetConnection* IncomingNetConnection = Cast<UNetConnection>(CustomPC->Player); + if (!IsValid(IncomingNetConnection) || !IncomingNetConnection->PlayerId.IsValid()) + { + // Not a networked player controller, or there's no player ID. + return; + } + + TSharedPtr<IOnlineIdentity, ESPMode::ThreadSafe> Identity = Subsystem->GetIdentityInterface(); + TSharedPtr<IOnlineVoiceAdmin, ESPMode::ThreadSafe> VoiceAdmin = Online::GetVoiceAdminInterface(Subsystem); + + // For the channel name you could use the current session ID. It's up to you + // to choose an appropriate value based on how you want to group players in + // voice chat. + FString ChannelName = Session->GetNamedSession("MyLocalSessionName")->GetSessionIdStr(); + + TArray<TSharedRef<const FUniqueNetId>> TargetUserIds; + TargetUserIds.Add(IncomingNetConnection->PlayerId.GetUniqueNetId().ToSharedRef()); + VoiceAdmin->CreateChannelCredentials( + *Identity->GetUniquePlayerId(0), // This will get the "dedicated server" ID. + ChannelName, + TargetUserIds, + FOnVoiceAdminCreateChannelCredentialsComplete::CreateUObject( + this, + &AarnocMainGameModeBase::IssuedCredentialsForPlayer, + ChannelName, + CustomPC)); } AarnocMainGameModeBase::AarnocMainGameModeBase() @@ -100,3 +139,20 @@ void AarnocMainGameModeBase::RegisterExistingPlayers() bExistingPlayersRegistered = true; } + +void AarnocMainGameModeBase::IssuedCredentialsForPlayer(const FOnlineError& Result, const FUniqueNetId& LocalUserId, + const TArray<FVoiceAdminChannelCredentials>& Credentials, FString InChannelName, AARNOPlayerController* NewPlayer) +{ + if (!Result.WasSuccessful()) + { + return; + } + + // We're making one CreateChannelCredentials call per player, so we can assume that the only entry in the + // results is for the player this callback is associated with. If you were requesting credentials for multiple + // target players, you'd have to iterate through Credentials to find the matching "TargetUserId" field. + if (IsValid(NewPlayer)) + { + NewPlayer->JoinVoiceChannel(InChannelName, Credentials[0].ChannelCredentials); + } +} diff --git a/Source/arnocMain/arnocMainGameModeBase.h b/Source/arnocMain/arnocMainGameModeBase.h index b5d3cd3..153b26b 100644 --- a/Source/arnocMain/arnocMainGameModeBase.h +++ b/Source/arnocMain/arnocMainGameModeBase.h @@ -3,9 +3,11 @@ #pragma once #include "CoreMinimal.h" +#include "ARNOPlayerController.h" #include "GameFramework/GameModeBase.h" #include "OnlineSubsystem.h" #include "OnlineSubsystemUtils.h" +#include "RedpointEOSInterfaces/Private/Interfaces/OnlineVoiceAdminInterface.h" #include "arnocMainGameModeBase.generated.h" /** @@ -26,4 +28,11 @@ public: private: bool bExistingPlayersRegistered; + + void IssuedCredentialsForPlayer( + const FOnlineError& Result, + const FUniqueNetId& LocalUserId, + const TArray<FVoiceAdminChannelCredentials>& Credentials, + FString InChannelName, + AARNOPlayerController* NewPlayer); }; -- GitLab