C++ 在 Unreal 中为游戏增加实时音视频互动的教程详解

2020-05-29 11:02:26于丽

覆盖 BeginPlay/EndPlay

//VideoCallPlayerController.h
...
UCLASS()
class AGORAVIDEOCALL_API AVideoCallPlayerController : public APlayerController
{
 GENERATED_BODY()
public:
 ...
 void BeginPlay() override;
 void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
 ...
};
//VideoCallPlayerController.cpp
void AVideoCallPlayerController::BeginPlay()
{
 Super::BeginPlay();
 //initialize wigets
 if (wEnterChannelWidget) // Check if the Asset is assigned in the blueprint.
 {
 // Create the widget and store it.
 if (!EnterChannelWidget)
 {
 EnterChannelWidget = CreateWidget<UEnterChannelWidget>(this, wEnterChannelWidget);
 EnterChannelWidget->SetVideoCallPlayerController(this);
 }
 // now you can use the widget directly since you have a referance for it.
 // Extra check to make sure the pointer holds the widget.
 if (EnterChannelWidget)
 {
 //let add it to the view port
 EnterChannelWidget->AddToViewport();
 }
 //Show the Cursor.
 bShowMouseCursor = true;
 }
 if (wVideoCallWidget)
 {
 if (!VideoCallWidget)
 {
 VideoCallWidget = CreateWidget<UVideoCallWidget>(this, wVideoCallWidget);
 VideoCallWidget->SetVideoCallPlayerController(this);
 }
 if (VideoCallWidget)
 {
 VideoCallWidget->AddToViewport();
 }
 VideoCallWidget->SetVisibility(ESlateVisibility::Collapsed);
 }
 //create video call and switch on the EnterChannelWidget
 VideoCallPtr = MakeUnique<VideoCall>();
 FString Version = VideoCallPtr->GetVersion();
 Version = "Agora version: " + Version;
 EnterChannelWidget->UpdateVersionText(Version);
 SwitchOnEnterChannelWidget(std::move(VideoCallPtr));
}
void AVideoCallPlayerController::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
 Super::EndPlay(EndPlayReason);
}

这时你可能注意到EnterChannelWidget和VideoCallWidget方法被标记为错误,那是因为它们还没有实现。我们将在接下来的步骤中实现它们。

增加 StartCall/EndCall

//VideoCallPlayerController.h
...
UCLASS()
class AGORAVIDEOCALL_API AVideoCallPlayerController : public APlayerController
{
 GENERATED_BODY()
public:
 ...
 void StartCall(
 TUniquePtr<VideoCall> PassedVideoCallPtr,
 const FString& ChannelName,
 const FString& EncryptionKey,
 const FString& EncryptionType
 );
 void EndCall(TUniquePtr<VideoCall> PassedVideoCallPtr);
 ...
};
//VideoCallPlayerController.cpp
void AVideoCallPlayerController::StartCall(
 TUniquePtr<VideoCall> PassedVideoCallPtr,
 const FString& ChannelName,
 const FString& EncryptionKey,
 const FString& EncryptionType)
{
 SwitchOnVideoCallWidget(std::move(PassedVideoCallPtr));
 VideoCallWidget->OnStartCall(
 ChannelName,
 EncryptionKey,
 EncryptionType);
}
void AVideoCallPlayerController::EndCall(TUniquePtr<VideoCall> PassedVideoCallPtr)
{
 SwitchOnEnterChannelWidget(std::move(PassedVideoCallPtr));
}

增加打开另一个小工具的方法

//VideoCallPlayerController.h
...
UCLASS()
class AGORAVIDEOCALL_API AVideoCallPlayerController : public APlayerController
{
 GENERATED_BODY()
public:
 ...
 void SwitchOnEnterChannelWidget(TUniquePtr<VideoCall> PassedVideoCallPtr);
 void SwitchOnVideoCallWidget(TUniquePtr<VideoCall> PassedVideoCallPtr);
 ...
};
//VideoCallPlayerController.cpp
void AVideoCallPlayerController::SwitchOnEnterChannelWidget(TUniquePtr<VideoCall> PassedVideoCallPtr)
{
 if (!EnterChannelWidget)
 {
 return;
 }
 EnterChannelWidget->SetVideoCall(std::move(PassedVideoCallPtr));
 EnterChannelWidget->SetVisibility(ESlateVisibility::Visible);
}
void AVideoCallPlayerController::SwitchOnVideoCallWidget(TUniquePtr<VideoCall> PassedVideoCallPtr)
{
 if (!VideoCallWidget)
 {
 return;
 }
 VideoCallWidget->SetVideoCall(std::move(PassedVideoCallPtr));
 VideoCallWidget->SetVisibility(ESlateVisibility::Visible);
}