> For the complete documentation index, see [llms.txt](https://docs.ggwp.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ggwp.com/ggwp-client-sdk/integration-guide/unreal.md).

# Unreal

**Initial Setup**

Before the SDK is able to capture audio, you must initialize it by calling:

{% code overflow="wrap" %}

```csharp
FGGWPSDKModule& GgwpSDK = FModuleManager::Get().LoadModuleChecked<FGGWPSDKModule>(TEXT("GGWPSDK"));
GgwpResult Result = GgwpSDK.InitializeSDK("YOUR_CUSTOMER_ID");
```

{% endcode %}

After successful initialization authorize either with Code Auth (recommended) or a static key based auth (simpler, easier setup).

**Vivox**

The Unreal plugin will attempt to self-configure. If `VivoxCore` is a plugin present and enabled in the project uproject file, GGWP plugin will build Vivox-specific helpers. Please make sure to include `VivoxCore` in your `${project}.uproject` to ensure the Vivox configuration functions are built.

Please initialize and authorize the GGWP SDK as early as possible:

{% code overflow="wrap" %}

```csharp
FGGWPSDKModule& GgwpSDK = FModuleManager::Get().LoadModuleChecked(TEXT("GGWPSDK"));
GgwpResult InitResult = GgwpSDK.InitializeSDK("YOUR_CUSTOMER_ID");
```

{% endcode %}

and then either use dynamic token:

{% code overflow="wrap" %}

```csharp
GgwpSDK.GetAuthManager()->SubscribeAuthUpdates(
    FAuthUpdatesDelegate::FDelegate::CreateLambda([](const GGWP::AuthStatus& AuthStatus) {
			UE_LOG(LogTemp, Display, TEXT("Auth status is %d"), AuthStatus.Status);
    })
);

// Perform auth
FAuthCompletionDelegate AuthCompletion;
AuthCompletion.BindLambda([this, AuthPromise](GgwpResult Result) {
	UE_LOG(LogTemp, TEXT("Auth completion status: %d"), Result);
});

FString CorrectCode = FetchCode();
AuthManager->ExchangeAuthCode(CorrectCode, AuthCompletion);
```

{% endcode %}

or static

{% code overflow="wrap" %}

```csharp
FAuthCompletionDelegate AuthCompletion;
AuthCompletion.BindLambda([this, AuthPromise](GgwpResult Result) {
	UE_LOG(LogTemp, TEXT("Auth completion status: %d"), Result);
});

AuthManager->SetStaticAuth("SomeKey", "SomeSigningKey", AuthCompletion);
```

{% endcode %}

After the login succeeds, you can start sending the voice chunks into the SDK:

{% code overflow="wrap" %}

```csharp
VivoxVoiceClient = &static_cast<FVivoxCoreModule *>(&FModuleManager::Get().LoadModuleChecked(TEXT("VivoxCore")))->VoiceClient();
auto DefaultConfig = VivoxConfig();

// This will automatically bind the capture callback for you.
// If you bind your own callbacks to Vivox, please bind
// FGGWPSDKodule::VivoxBeforeCaptureAudioSent to `pf_on_audio_unit_before_capture_audio_sent`.
GgwpResult ConfigBindResult = GgwpSDK->BindCaptureCallback(DefaultConfig);
VivoxVoiceClient->Initialize(DefaultConfig);
```

{% endcode %}

You can either rely on logging built into the GGWPSDK itself which logs under the `GGWPSDK` log group, or you can bind your own delegate:

{% code overflow="wrap" %}

```csharp
GgwpSDK->GetLogDelegate().AddStatic(&FMyVoiceChatModule::LogMessage);
```

{% endcode %}

This is highly recommended as these log messages convey a lot of useful information about the operation of the SDK. You can use `FGGWPLogMessage::StatusCode` to react to these states in your code.

Please see the Unreal Sample App for a working example.<br>

**EOS Voice**

EOS-specific code will automatically build if an `OnlineSubsystemEOS` plugin is present and enabled in the uproject file.

Please initialize the GGWPSDK as early as possible as starting a session is a prerequisite to calling all the other functions. Once an EOS user has joined the voice chat channel, call `BindCaptureCallback` to automatically wire the audio processor.

{% code overflow="wrap" fullWidth="false" %}

```csharp
auto GgwpSDK = static_cast<FGGWPSDKModule *>(&FModuleManager::Get().LoadModuleChecked(TEXT("GGWPSDK")));
GgwpResult StartResult = GgwpSDK->StartSession("unrealsession", "unrealuser", FGGWPSDKModule::FCustomerAuthParams {
	"unrealtestcustomer",
	GGWP_AUTH_KEY,
	GGWP_SIGNING_KEY
});

//
// SNIP, joining voice
//

IVoiceChatUser* VoiceChatUser = EOSSubsystem->GetVoiceChatUserInterface(*NetId);

if (!VoiceChatUser) {
    UE_LOG(LogTemp, Error, TEXT("Cannot get VoiceChatUser"));
    return;
}

GgwpSDK->BindCaptureCallback(VoiceChatUser);
```

{% endcode %}

#### Discord SDK

In order to allow GGWP SDK to capture audio of the voice channels, you need to call

{% code overflow="wrap" %}

```csharp
FGGWPSDKModule& GgwpSDK = FModuleManager::Get().LoadModuleChecked<FGGWPSDKModule>(TEXT("GGWPSDK"));
GgwpSDK.StartCall(DiscordClient, "MyLobbyId");
```

{% endcode %}

This wrapper will ensure the callbacks are wired in the right way and that the audio is relayed in the right format. If you need to bind into the voice capture callbacks yourself, please enqueue the audio directly while following the same pattern as the `StartCall` wrapper.

Please see the Discord Example App for more details.
