https://docs.unrealengine.com/4.26/zh-CN/SharingAndReleasing/XRDevelopment/VR/DevelopVR/ContentSetup/
Epic Games
[SystemSettings]
vr.PixelDensity=1
r.SeparateTranslucency=0
r.HZBOcclusion=0
r.MotionBlurQuality=0
r.PostProcessAAQuality=3
r.BloomQuality=1
r.EyeAdaptationQuality=0
r.AmbientOcclusionLevels=0
r.SSR.Quality=1
r.DepthOfFieldQuality=0
r.SceneColorFormat=2
r.TranslucencyVolumeBlur=0
r.TranslucencyLightingVolumeDim=4
r.MaxAnisotropy=8
r.LensFlareQuality=0
r.SceneColorFringeQuality=0
r.FastBlurThreshold=0
r.SSR.MaxRoughness=0.1
r.rhicmdbypass=0
sg.EffectsQuality=2
sg.PostProcessQuality=0
[OnlineSubsystem]
DefaultPlatformService=Oculus
[OnlineSubsystemOculus]
bEnabled=true
OculuesAppId=
RiftAppId=
https://learn.unrealengine.com/course/3746907/module/7254773?moduletoken=UHxxnDLPW8Rp-7N-q4JkIjEQEsOt3snTmaKK-rCvMCbzh~y0iaykoFQik9vT6VYT&LPId=117565
bool FShaderPipelineCache::Open(FString const& Name, EShaderPlatform Platform)
{
......
if(bReady)
{
uint64 PreCompileMask = (uint64)CVarPSOFileCachePreCompileMask.GetValueOnAnyThread();
//FPipelineFileCache::SetGameUsageMaskWithComparison(PreCompileMask, PreCompileMaskComparison);
FShaderPipelineCache::SetGameUsageMaskWithComparison(PreCompileMask, PreCompileMaskComparison);
......
}
[DevOptions.Shaders]
NeedsShaderStableKeys=true
https://learn.unrealengine.com/course/3746970/module/7254916?moduletoken=UHxxnDLPW8Rp-7N-q4JkIuBOIC4F1jL4A39qvRh5ceQMXjghbjAvwPyS~Pd5rj0G&LPId=117565
传送前在传送点位置处进行一条垂直200的射线检测,优化传送点位置
// Fill out your copyright notice in the Description page of Project Settings.
using UnrealBuildTool;
public class Darts : ModuleRules
{
public Darts(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] {
"Core",
"CoreUObject",
"Engine",
"InputCore",
"LibOVRPlatform"
});
PrivateDependencyModuleNames.AddRange(new string[] {
"OnlineSubsystem",
"OnlineSubsystemOculus",
// "LibOVRAvatar", this is useless
});
// Uncomment if you are using Slate UI
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
// Uncomment if you are using online features
// PrivateDependencyModuleNames.Add("OnlineSubsystem", "OnlineSubsystemOculus","LibOVRAvatar",);
// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
if ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64))
{
//PrivateDependencyModuleNames.Add("LibOVRPlatform");
PublicDelayLoadDLLs.Add("LibOVRPlatform64_1.dll");
}
}
}
OculusOSS.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Online.h"
#include "OVR_Platform.h"
#include "OnlineSubsystemOculus.h"
#include "GameFramework/Actor.h"
#include "OculusOSS.generated.h"
UCLASS()
class DARTS_API AOculusOSS : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AOculusOSS(const FObjectInitializer& ObjectInitializer);
//AOculusOSS(); //previous constructor
FOnlineSubsystemOculus* OSS;
private:
FString MyPlayerName;
FString MyPlayerID;
FOnSessionUserInviteAcceptedDelegate OnSessionUserInviteAcceptedDelegate;
FOnJoinSessionCompleteDelegate OnJoinSessionCompleteDelegate;
FOnCreateSessionCompleteDelegate OnCreateSessionCompleteDelegate;
FOnStartSessionCompleteDelegate OnStartSessionCompleteDelegate;
FOnDestroySessionCompleteDelegate OnDestroySessionCompleteDelegate;
static FString AcceptedInviteFrom;
static FOnlineSessionSearchResult AcceptedInvite;
//matchmaking:
TSharedPtr SearchSettings;
FOnMatchmakingCompleteDelegate OnMatchmakingCompleteDelegate;
FOnCancelMatchmakingCompleteDelegate OnCancelMatchmakingCompleteDelegate;
FDelegateHandle ovrMessage_Notification_ApplicationLifecycle_LaunchIntentChangedHandle;
void OnApplicationLifecycle_LaunchIntentChanged(ovrMessageHandle Message, bool bIsError);
ovrRichPresenceOptionsHandle ovr_RichPresenceOptions_Handle = NULL;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
FDelegateHandle OnLoginCompleteDelegateHandle;
FDelegateHandle OnJoinSessionCompleteDelegateHandle;
FDelegateHandle OnDestroySessionCompleteDelegateHandle;
FDelegateHandle OnCreateSessionCompleteDelegateHandle;
FDelegateHandle OnStartSessionCompleteDelegateHandle;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
virtual void OnLoginComplete(int32 LocalUserNum, bool bWasSuccessful, const FUniqueNetId& UserId, const FString& Error);
void OnPrivilegeCheck(const FUniqueNetId& UserId, EUserPrivileges::Type Privilege, uint32 CheckResult);
void OnSessionUserInviteAccepted(const bool bWasSuccessful, const int32 ControllerId, TSharedPtr UserId, const FOnlineSessionSearchResult& InviteResult);
void OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type JoinResult);
void OnCreateSessionComplete(FName SessionName, bool bWasSuccessful);
void OnStartOnlineGameComplete(FName SessionName, bool bWasSuccessful);
void OnDestroySessionComplete(FName SessionName, bool bWasSuccessful);
UFUNCTION(BlueprintImplementableEvent, Category = Identity)
void OnPlayerNameUpdate(const FString& PlayerName);
UFUNCTION(BlueprintImplementableEvent, Category = Identity)
void OnPlayerIDUpdate(const FString& PlayerID);
UFUNCTION(BlueprintCallable, Category = OculusSession)
void CreateSession();
UFUNCTION(BlueprintImplementableEvent, Category = OculusSession)
void OnCreateSessionCompleteBP(FName SessionName, bool bWasSuccessful);
UFUNCTION(BlueprintImplementableEvent, Category = OculusSession)
void OnJoinSessionCompleteBP(FName SessionName, bool bWasSuccessful);
UFUNCTION(BlueprintImplementableEvent, Category = OculusSession)
void OnLoginCompleteBP(bool bWasSuccessful);
UFUNCTION(BlueprintCallable, Category = OculusSession)
void LaunchUserInviteFlow();
UFUNCTION(BlueprintCallable, Category = OculusSession)
void LeavingMap();
UFUNCTION(BlueprintCallable, Category = OculusSession)
void PlayerLoggedOut(const FString& PlayerID);
UFUNCTION(BlueprintCallable, Category = OculusSession)
void TestSessionInvite();
UFUNCTION(BlueprintCallable, Category = OculusSession)
bool StartMatchmaking(const FString& PoolName);
UFUNCTION(BlueprintCallable, Category = OculusSession)
bool CancelMatchmaking(const FName SessionName);
void OnMatchmakingComplete(FName SessionName, bool bWasSuccessful);
UFUNCTION(BlueprintImplementableEvent, Category = OculusSession)
void OnMatchmakingCompleteBP(FName SessionName, bool bWasSuccessful);
//UFUNCTION(BlueprintImplementableEvent, Category = OculusSession)
void OnCancelMatchmakingComplete(FName SessionName, bool bWasSuccessful);
UFUNCTION(BlueprintImplementableEvent, Category = OculusSession)
void OnCancelMatchmakingCompleteBP(FName SessionName, bool bWasSuccessful);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = OculusSession)
FString MatchmakingStatus;
//Rich Presence:
UFUNCTION(BlueprintCallable, Category = OculusRichPresence)
void RichPresenceOptions_Destroy();
UFUNCTION(BlueprintCallable, Category = OculusRichPresence)
void SetRichPresenceAPIName(FString RichPresenceAPIName);
UFUNCTION(BlueprintCallable, Category = OculusRichPresence)
void SetRichPresenceArgsString(FString RichPresenceArgsKey, FString RichPresenceArgsValue);
UFUNCTION(BlueprintCallable, Category = OculusRichPresence)
void RichPresenceClearArgs();
UFUNCTION(BlueprintCallable, Category = OculusRichPresence)
void SetRichPresenceCurrentCapacity(uint8 CurrentCapacity);
UFUNCTION(BlueprintCallable, Category = OculusRichPresence)
void SetRichPresenceDeeplinkMessageOverride(FString DeeplinkMessageOverride);
UFUNCTION(BlueprintCallable, Category = OculusRichPresence)
void SetRichPresenceSetEndTime(FString EndTime);
/*
//$TODO need to create UENUM to map to this structure
//UFUNCTION(BlueprintCallable, Category = OculusRichPresence)
//bool SetRichPresenceExtraContext(FString ExtraContext);
*/
UFUNCTION(BlueprintCallable, Category = OculusRichPresence)
void SetRichPresenceIsIdle(bool IsIdle);
UFUNCTION(BlueprintCallable, Category = OculusRichPresence)
void SetRichPresenceIsJoinable(bool IsJoinable);
UFUNCTION(BlueprintCallable, Category = OculusRichPresence)
void SetRichPresenceJoinableId(FString JoinableId);
UFUNCTION(BlueprintCallable, Category = OculusRichPresence)
void SetRichPresenceMaxCapacity(uint8 MaxCapacity);
UFUNCTION(BlueprintCallable, Category = OculusRichPresence)
void SetRichPresenceStartTime(FString StartTime);
//Destinations:
void OnReceivedDeepLinkMessage(ovrLaunchDetailsHandle LaunchDetails);
UFUNCTION(BlueprintImplementableEvent, Category = OculusRichPresence)
void OnReceivedDeepLinkMessageBP(const FString& DLMessage);
};
OculusOSS.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "OculusOSS.h"
#include "Darts.h"
#include "Runtime/Engine/Classes/GameFramework/GameModeBase.h"
FString AOculusOSS::AcceptedInviteFrom;
FOnlineSessionSearchResult AOculusOSS::AcceptedInvite;
// Sets default values
AOculusOSS::AOculusOSS(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
UE_LOG(LogTemp, Verbose, TEXT("In the AOculusOSS constructor"));
if (IsRunningCommandlet())
{
FModuleManager::Get().LoadModule(TEXT("OnlineSubsystem"));
}
OSS = static_cast(IOnlineSubsystem::Get());
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
AcceptedInviteFrom.Empty(); // empty signified no invites are outstanding
OnCreateSessionCompleteDelegate = FOnCreateSessionCompleteDelegate::CreateUObject(this, &AOculusOSS::OnCreateSessionComplete);
OnSessionUserInviteAcceptedDelegate = FOnSessionUserInviteAcceptedDelegate::CreateUObject(this, &AOculusOSS::OnSessionUserInviteAccepted);
OnJoinSessionCompleteDelegate = FOnJoinSessionCompleteDelegate::CreateUObject(this, &AOculusOSS::OnJoinSessionComplete);
OnStartSessionCompleteDelegate = FOnStartSessionCompleteDelegate::CreateUObject(this, &AOculusOSS::OnStartOnlineGameComplete);
OnDestroySessionCompleteDelegate = FOnDestroySessionCompleteDelegate::CreateUObject(this, &AOculusOSS::OnDestroySessionComplete);
ovrMessage_Notification_ApplicationLifecycle_LaunchIntentChangedHandle =
OSS->GetNotifDelegate(ovrMessage_Notification_ApplicationLifecycle_LaunchIntentChanged).AddUObject(this, &AOculusOSS::OnApplicationLifecycle_LaunchIntentChanged);
if (!ovr_RichPresenceOptions_Handle)
{
ovr_RichPresenceOptions_Handle = ovr_RichPresenceOptions_Create();
}
}
// Called when the game starts or when spawned
void AOculusOSS::BeginPlay()
{
Super::BeginPlay();
if (Online::GetSessionInterface().IsValid())
{
Online::GetSessionInterface()->AddOnDestroySessionCompleteDelegate_Handle(OnDestroySessionCompleteDelegate);
Online::GetSessionInterface()->AddOnJoinSessionCompleteDelegate_Handle(OnJoinSessionCompleteDelegate);
Online::GetSessionInterface()->AddOnSessionUserInviteAcceptedDelegate_Handle(OnSessionUserInviteAcceptedDelegate);
}
auto OculusIdentityInterface = Online::GetIdentityInterface();
if (!OculusIdentityInterface.IsValid())
{
UE_LOG(LogTemp, Error, TEXT("No OculusIdentityInterface found!"));
return;
}
OnLoginCompleteDelegateHandle = OculusIdentityInterface->AddOnLoginCompleteDelegate_Handle(0, FOnLoginCompleteDelegate::CreateUObject(this, &AOculusOSS::OnLoginComplete));
if (OculusIdentityInterface->AutoLogin(0))
{
UE_LOG(LogTemp, Verbose, TEXT("Waiting for login response from oculus...."));
}
}
// Called every frame
void AOculusOSS::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AOculusOSS::OnApplicationLifecycle_LaunchIntentChanged(ovrMessageHandle Message, bool bIsError)
{
UE_LOG(LogTemp, Verbose, TEXT("In OnApplicationLifecycle_LaunchIntentChanged"));
if (bIsError)
{
//error
UE_LOG(LogTemp, Verbose, TEXT("Got an error retrieving the launch intent"));
return;
}
//do something
//const char*
FString launchMessage;
const char* tesmps = ovr_Message_GetString(Message);
//UE_LOG(LogTemp, Verbose, TEXT("LaunchMessage: %s"), launchMessage);
if (launchMessage.Find(TEXT("LaunchType"), ESearchCase::IgnoreCase, ESearchDir::FromStart, 0))
{
UE_LOG(LogTemp, Verbose, TEXT("Found LaunchType "));
}
auto LaunchDetails = ovr_ApplicationLifecycle_GetLaunchDetails();
auto LaunchType = ovr_LaunchDetails_GetLaunchType(LaunchDetails);
switch (LaunchType)
{
case ovrLaunchType_Unknown:
UE_LOG(LogTemp, Verbose, TEXT("Found LaunchType Unknown "));
break;
case ovrLaunchType_Normal:
UE_LOG(LogTemp, Verbose, TEXT("Found LaunchType Normal "));
break;
case ovrLaunchType_Invite:
UE_LOG(LogTemp, Verbose, TEXT("Found LaunchType Invite "));
break;
case ovrLaunchType_Coordinated:
UE_LOG(LogTemp, Verbose, TEXT("Found LaunchType Coordinated "));
break;
case ovrLaunchType_Deeplink:
{
UE_LOG(LogTemp, Verbose, TEXT("Found LaunchType Deep link "));
OnReceivedDeepLinkMessage(LaunchDetails);
break;
}
default:
UE_LOG(LogTemp, Verbose, TEXT("Found LaunchType DEFAULT CASE "));
break;
}
}
void AOculusOSS::OnReceivedDeepLinkMessage(ovrLaunchDetailsHandle LaunchDetails)
{
UE_LOG(LogTemp, Verbose, TEXT("Made it to OnReceivedDeepLinkMessage"));
//Parse the deep link message here and then call the BP event
auto DeepLinkMessage = ovr_LaunchDetails_GetDeeplinkMessage(LaunchDetails);
FString DeepLinkMessageFS(DeepLinkMessage);
UE_LOG(LogTemp, Verbose, TEXT("OnReceivedDeepLinkMessage: DeepLink Message: %s"), *DeepLinkMessageFS);
//TSharedPtr JsonObject = MakeShareable(new FJsonObject());
//TSharedRef< TJsonReader<> > JsonReader = TJsonReaderFactory<>::Create()
//const TSharedRef< TJsonReader<> >& Reader = TJsonReaderFactory<>::Create(DeepLinkMessageFS);
//if (FJsonSerializer::Deserialize(Reader, JsonObject) && JsonObject.IsValid())
//{
//UE_LOG(LogTemp, Verbose, TEXT("Parsed the JSON"));
//}
//else
//UE_LOG(LogTemp, Verbose, TEXT("Failed to parse JSON. Error: '%s'"), *Reader->GetErrorMessage());
int32 index = DeepLinkMessageFS.Find(TEXT("command"), ESearchCase::IgnoreCase, ESearchDir::FromStart);
UE_LOG(LogTemp, Verbose, TEXT("Index: %i"), index);
FString CommandString;
if (index > -1)
{
UE_LOG(LogTemp, Verbose, TEXT("Index: %i"), index);
CommandString = DeepLinkMessageFS.RightChop(index + 8); //skip the 'command:' char and get the next word
UE_LOG(LogTemp, Verbose, TEXT("Command: %s"), *CommandString);
UE_LOG(LogTemp, Verbose, TEXT("Calling OnReceivedDeepLinkMessageBP"));
OnReceivedDeepLinkMessageBP(CommandString);
}
//auto DeepLinkAPIName = ovr_LaunchDetails_GetDestinationApiName(LaunchDetails); //this requires an updated header and .lib that isn't in 4.24 so commenting out for now.
}
void AOculusOSS::OnLoginComplete(int32 LocalUserNum, bool bWasSuccessful, const FUniqueNetId& UserId, const FString& Error)
{
auto OculusIdentityInterface = Online::GetIdentityInterface();
OculusIdentityInterface->ClearOnLoginCompleteDelegate_Handle(0, OnLoginCompleteDelegateHandle);
OculusIdentityInterface->GetUserPrivilege(
UserId,
EUserPrivileges::CanPlay,
IOnlineIdentity::FOnGetUserPrivilegeCompleteDelegate::CreateUObject(this, &AOculusOSS::OnPrivilegeCheck));
if (!bWasSuccessful)
{
UE_LOG(LogTemp, Warning, TEXT("Unable to login with oculus! %s"), *Error);
return;
}
UE_LOG(LogTemp, Verbose, TEXT("Logged in successfully to oculus!"));
// Get the Oculus ID
MyPlayerName = OculusIdentityInterface->GetPlayerNickname(UserId);
MyPlayerID = UserId.ToString();
UE_LOG(LogTemp, Verbose, TEXT("Welcome %s!"), *MyPlayerName);
OnPlayerNameUpdate(MyPlayerName);
OnPlayerIDUpdate(MyPlayerID);
OnLoginCompleteBP(bWasSuccessful); //notify Blueprint of the call completion
}
void AOculusOSS::OnPrivilegeCheck(const FUniqueNetId& UserId, EUserPrivileges::Type Privilege, uint32 CheckResult)
{
if (CheckResult != (uint32)IOnlineIdentity::EPrivilegeResults::NoFailures)
{
UE_LOG(LogTemp, Error, TEXT("Arrg, you failed the entitlement check!"));
// Developers may want to just quit the game here.
MyPlayerName = TEXT("FAILED ENTITLEMENT CHECK");
OnPlayerNameUpdate(MyPlayerName);
return;
}
UE_LOG(LogTemp, Verbose, TEXT("You passed the entitlement check!"));
}
void AOculusOSS::OnSessionUserInviteAccepted(const bool bWasSuccessful, const int32 ControllerId, TSharedPtr UserId, const FOnlineSessionSearchResult& InviteResult)
{
UE_LOG(LogTemp, Verbose, TEXT("User has accepted an invitation with success = %d"), bWasSuccessful);
if (!bWasSuccessful)
{
UE_LOG(LogTemp, Error, TEXT("Did not successfully accept user invitation!"));
return;
}
//Check if I am in a session already and destroy it if so.
auto OculusSessionInterface = Online::GetSessionInterface();
auto Session = OculusSessionInterface->GetNamedSession(TEXT("Game"));
if (Session)
{
AcceptedInvite = InviteResult;
AcceptedInviteFrom = *UserId->ToString();
UE_LOG(LogTemp, Verbose, TEXT("Destroying existing session before trying to join new one"));
Online::GetSessionInterface()->DestroySession(TEXT("Game"), OnDestroySessionCompleteDelegate);
return; //exit so OnDestroySessionComplete will handle the join session call in this case
}
UE_LOG(LogTemp, Verbose, TEXT("Not in an existing session. Trying to join session from invitation"));
OculusSessionInterface->JoinSession(ControllerId, TEXT("Game"), InviteResult);
}
//TODO: legacy
void AOculusOSS::TestSessionInvite()
{
const bool bWasSuccessful = true;
TSharedPtr UserId = 0;
const int32 ControllerId = 0;
//const FOnlineSessionSearchResult & InviteResult;
if (!bWasSuccessful)
{
UE_LOG(LogTemp, Error, TEXT("Did not successfully invited user to the session!"));
return;
}
UE_LOG(LogTemp, Verbose, TEXT("Accepted invite to session. Joining session...."));
//Check if I am in a session already and destroy it if so.
auto OculusSessionInterface = Online::GetSessionInterface();
auto Session = OculusSessionInterface->GetNamedSession(TEXT("Game"));
if (Session)
{
OculusSessionInterface->DestroySession(TEXT("Game"), OnDestroySessionCompleteDelegate);
}
UE_LOG(LogTemp, Verbose, TEXT("Would call Join Session here"));
}
void AOculusOSS::OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type JoinResult)
{
UE_LOG(LogTemp, Verbose, TEXT("In OnJoinSessionComplete"));
auto OculusSessionInterface = Online::GetSessionInterface();
auto Session = OculusSessionInterface->GetNamedSession(SessionName);
FString TravelURL;
APlayerController* PlayerController = NULL;
//AGameModeBase *GameMode = NULL;
UWorld* const TheWorld = GetWorld();
if (!TheWorld)
{
UE_LOG(LogTemp, Warning, TEXT("The World Does Not Exist."));
return;
}
else
{
PlayerController = GetWorld()->GetFirstPlayerController();
auto gamemode = (AGameModeBase*)GetWorld()->GetAuthGameMode();
//gamemode->bUseSeamlessTravel = false;
UE_LOG(LogTemp, Verbose, TEXT("Seamless Travel Set to : %s"), gamemode->bUseSeamlessTravel ? TEXT("True") : TEXT("False"));
}
if (Session)
{
OculusSessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(OnJoinSessionCompleteDelegateHandle);
UE_LOG(LogTemp, Verbose, TEXT("Got back %s's session: %s"), *Session->OwningUserName, *SessionName.ToString());
if (*Session->OwningUserId == *Online::GetIdentityInterface()->GetUniquePlayerId(0)) // I am the owner
{
UE_LOG(LogTemp, Verbose, TEXT("I am the session owner and will host"));
//GetWorld()->ServerTravel(TEXT("/Game/Maps/Minimal_Default3?listen"));
}
else
{
UE_LOG(LogTemp, Verbose, TEXT("Not the session owner"));
if (PlayerController && OculusSessionInterface->GetResolvedConnectString(SessionName, TravelURL))
{
TravelURL = TravelURL + TEXT("?multiplayer=true"); //so the level blueprint will see that it was loaded in MP mode.
UE_LOG(LogTemp, Verbose, TEXT("Calling ClientTravel to: %s"), *TravelURL);
// Finally call the ClienTravel
PlayerController->ClientTravel(TravelURL, ETravelType::TRAVEL_Absolute);
}
}
auto gamemode = (AGameModeBase*)GetWorld()->GetAuthGameMode();
//gamemode->bUseSeamlessTravel = true; //after first travel, start using seamless travel.
UE_LOG(LogTemp, Verbose, TEXT("Seamless Travel Set to : %s"), gamemode->bUseSeamlessTravel ? TEXT("True") : TEXT("False"));
auto OculusVoiceInterface = Online::GetVoiceInterface();
auto OculusIdentityInterface = Online::GetIdentityInterface();
auto UserId = OculusIdentityInterface->GetUniquePlayerId(0);
OculusSessionInterface->StartSession(SessionName);//
auto RegisteredPlayers = Session->RegisteredPlayers; //get list of players in the session
for (auto RegisteredPlayer : RegisteredPlayers)
{
//don't register the local player, only the remote
if (RegisteredPlayer.Get() != *UserId.Get())
{
OculusVoiceInterface->RegisterRemoteTalker(RegisteredPlayer.Get());
OculusVoiceInterface->StartNetworkedVoice(0);
UE_LOG(LogTemp, Verbose, TEXT("Registered a Talker: %s"), *RegisteredPlayer.Get().ToString());
}
}
}
//call the BP event:
OnJoinSessionCompleteBP(SessionName, (JoinResult == EOnJoinSessionCompleteResult::Success));
}
bool AOculusOSS::StartMatchmaking(const FString& PoolName)
{
auto OculusSessionInterface = Online::GetSessionInterface();
if (OculusSessionInterface->IsPlayerInSession(TEXT("Game"), *Online::GetIdentityInterface()->GetUniquePlayerId(0).Get()))
{
//need to kill the existing session
OculusSessionInterface->DestroySession(TEXT("Game"));
}
UE_LOG(LogTemp, Verbose, TEXT("Starting Matchmaking"));
MatchmakingStatus = TEXT("Looking for a Match, X to cancel");
TArray< TSharedRef > LocalPlayers;
// Create a matchmaking for two people
auto SessionSettings = new FOnlineSessionSettings();
SessionSettings->NumPublicConnections = 2;
SearchSettings = MakeShareable(new FOnlineSessionSearch());
// Add the delegate
if (!OnMatchmakingCompleteDelegate.IsBound())
{
OnMatchmakingCompleteDelegate = FOnMatchmakingCompleteDelegate::CreateUObject(this, &AOculusOSS::OnMatchmakingComplete);
OculusSessionInterface->AddOnMatchmakingCompleteDelegate_Handle(OnMatchmakingCompleteDelegate);
}
// Search with this poolname
SearchSettings->QuerySettings.Set(FName(TEXT("OCULUSPOOL")), PoolName, EOnlineComparisonOp::Equals);
TSharedRef SearchSettingsRef = SearchSettings.ToSharedRef();
// Do the search
return OculusSessionInterface->StartMatchmaking(LocalPlayers, TEXT("Game"), *SessionSettings, SearchSettingsRef);
}
bool AOculusOSS::CancelMatchmaking(FName SessionName)
{
auto OculusSessionInterface = Online::GetSessionInterface();
// Add the delegate
if (!OnCancelMatchmakingCompleteDelegate.IsBound())
{
OnCancelMatchmakingCompleteDelegate = FOnCancelMatchmakingCompleteDelegate::CreateUObject(this, &AOculusOSS::OnCancelMatchmakingComplete);
OculusSessionInterface->AddOnCancelMatchmakingCompleteDelegate_Handle(OnCancelMatchmakingCompleteDelegate);
}
UE_LOG(LogTemp, Verbose, TEXT("Cancelling Matchmaking"));
MatchmakingStatus = TEXT("Cancelling Matchmaking");
return OculusSessionInterface->CancelMatchmaking(0, TEXT("Game"));
}
void AOculusOSS::OnCancelMatchmakingComplete(FName SessionName, bool bWasSuccessful)
{
UE_LOG(LogTemp, Verbose, TEXT("Matchmaking Cancel returned: %s"), bWasSuccessful ? TEXT("true") : TEXT("false"));
MatchmakingStatus = TEXT("Matchmaking Cancelled");
OnCancelMatchmakingCompleteBP(SessionName, bWasSuccessful);
}
void AOculusOSS::OnMatchmakingComplete(FName SessionName, bool bWasSuccessful)
{
if (!(bWasSuccessful && SearchSettings->SearchResults.Num() > 0))
{
UE_LOG(LogTemp, Error, TEXT("Did not successfully find a matchmaking session!"));
MatchmakingStatus = TEXT("Did not find a matchmaking session!");
return;
}
UE_LOG(LogTemp, Verbose, TEXT("Found a matchmaking session. Joining session...."));
MatchmakingStatus = TEXT("Round a matchmaking session!, Trying to join");
auto OculusSessionInterface = Online::GetSessionInterface();
OculusSessionInterface->JoinSession(0, SessionName, SearchSettings->SearchResults[0]);
OnMatchmakingCompleteBP(SessionName, bWasSuccessful); //tell the blueprint Matchmaking completed
}
void AOculusOSS::LaunchUserInviteFlow()
{
UE_LOG(LogTemp, Verbose, TEXT("Calling LaunchUserInviteFlow"));
//TODO: Confirm user is in a valid session/room before launching invite flow.
auto OculusIdentityInterface = Online::GetIdentityInterface();
auto UserId = OculusIdentityInterface->GetUniquePlayerId(0);
//test
ovrSystemVoipStatus v_status = ovr_Voip_GetSystemVoipStatus();
switch (v_status)
{
case ovrSystemVoipStatus::ovrSystemVoipStatus_Unknown:
UE_LOG(LogTemp, Verbose, TEXT("ovrSystemVoipStatus_Unknown"));
break;
case ovrSystemVoipStatus::ovrSystemVoipStatus_Unavailable:
UE_LOG(LogTemp, Verbose, TEXT(" ovrSystemVoipStatus_Unavailable"));
break;
case ovrSystemVoipStatus::ovrSystemVoipStatus_Suppressed:
UE_LOG(LogTemp, Verbose, TEXT(" ovrSystemVoipStatus_Suppressed"));
break;
case ovrSystemVoipStatus::ovrSystemVoipStatus_Active:
UE_LOG(LogTemp, Verbose, TEXT(" ovrSystemVoipStatus_Active"));
break;
};
ovrRequest RequestId1 = ovr_Room_GetCurrent();
OSS->AddRequestDelegate(RequestId1, FOculusMessageOnCompleteDelegate::CreateLambda([this](ovrMessageHandle Message, bool bIsError)
{
// ovrMessageHandle can be handled just like in the native SDK here to get the room
if (!ovr_Message_IsError(Message))
{
ovrRoomHandle room = ovr_Message_GetRoom(Message);
UE_LOG(LogTemp, Verbose, TEXT("Called ovr_Room_GetCurrent()"));
ovrRequest RequestId = ovr_Room_LaunchInvitableUserFlow(ovr_Room_GetID(room));
UE_LOG(LogTemp, Verbose, TEXT("RoomID: %llu"), ovr_Room_GetID(room));
}
else
{
const ovrErrorHandle error = ovr_Message_GetError(Message);
UE_LOG(LogTemp, Verbose, TEXT("Received get room failure: %s"), ovr_Error_GetMessage(error));
printf("Received get room failure: %s\n", ovr_Error_GetMessage(error));
}
}));
}
void AOculusOSS::LeavingMap()
{
auto OculusVoiceInterface = Online::GetVoiceInterface();
auto OculusIdentityInterface = Online::GetIdentityInterface();
auto UserId = OculusIdentityInterface->GetUniquePlayerId(0);
if (OculusVoiceInterface.IsValid())
{
//OculusVoiceInterface->RegisterRemoteTalker(RegisteredPlayer.Get());
OculusVoiceInterface->StopNetworkedVoice(0);
OculusVoiceInterface->RemoveAllRemoteTalkers();
//Online::GetVoiceInterface()->StartNetworkedVoice(0);
UE_LOG(LogTemp, Verbose, TEXT("Ending VoIP"));
}
}
void AOculusOSS::PlayerLoggedOut(const FString& PlayerID)
{
//UE_LOG(LogTemp, Verbose, TEXT("AOculusOSS::PlayerLoggedOut - %i"), UserID);
auto OculusVoiceInterface = Online::GetVoiceInterface();
auto OculusIdentityInterface = Online::GetIdentityInterface();
auto UserId = OculusIdentityInterface->GetUniquePlayerId(0); //not right if called on server when a different player leaves?
UE_LOG(LogTemp, Verbose, TEXT("AOculusOSS::PlayerLoggedOut - %s"), *PlayerID);
}
void AOculusOSS::CreateSession()
{
auto OculusSessionInterface = Online::GetSessionInterface();
if (!OculusSessionInterface.IsValid())
{
return;
}
UE_LOG(LogTemp, Verbose, TEXT("Trying to create a session"));
OnCreateSessionCompleteDelegateHandle = OculusSessionInterface->AddOnCreateSessionCompleteDelegate_Handle(OnCreateSessionCompleteDelegate);
TSharedPtr SessionSettings = MakeShareable(new FOnlineSessionSettings());
SessionSettings->NumPublicConnections = 4;
SessionSettings->bShouldAdvertise = true;
OculusSessionInterface->CreateSession(/* Hosting Player Num*/ 0, TEXT("Game"), *SessionSettings);
}
void AOculusOSS::OnCreateSessionComplete(FName SessionName, bool bWasSuccessful)
{
auto OculusSessionInterface = Online::GetSessionInterface();
if (!OculusSessionInterface.IsValid())
{
return;
}
OculusSessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(OnCreateSessionCompleteDelegateHandle);
UE_LOG(LogTemp, Verbose, TEXT("CreateSession Call complete and was: %d"), bWasSuccessful);
auto Session = OculusSessionInterface->GetNamedSession(SessionName);
if (Session)
{
UE_LOG(LogTemp, Verbose, TEXT("Session owned by %s"), *Session->OwningUserName);
UE_LOG(LogTemp, Verbose, TEXT("Session state: %s"), EOnlineSessionState::ToString(Session->SessionState));
}
if (bWasSuccessful)
{
// Set the StartSession delegate handle
OnStartSessionCompleteDelegateHandle = OculusSessionInterface->AddOnStartSessionCompleteDelegate_Handle(OnStartSessionCompleteDelegate);
// Our StartSessionComplete delegate should get called after this
OculusSessionInterface->StartSession(SessionName);
}
//Tell the BP we have tried to create a session
OnCreateSessionCompleteBP(SessionName, bWasSuccessful);
}
void AOculusOSS::OnStartOnlineGameComplete(FName SessionName, bool bWasSuccessful)
{
GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("OnStartSessionComplete %s, %d"), *SessionName.ToString(), bWasSuccessful));
// Get the Online Subsystem so we can get the Session Interface
IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get();
if (OnlineSub)
{
// Get the Session Interface to clear the Delegate
IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();
if (Sessions.IsValid())
{
// Clear the delegate, since we are done with this call
Sessions->ClearOnStartSessionCompleteDelegate_Handle(OnStartSessionCompleteDelegateHandle);
}
}
// If the start was successful, we can open a NewMap if we want. Make sure to use "listen" as a parameter!
if (bWasSuccessful)
{
UE_LOG(LogTemp, Verbose, TEXT("Started the Session"));
}
}
void AOculusOSS::OnDestroySessionComplete(FName SessionName, bool bWasSuccessful)
{
GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("OnDestroySessionComplete %s, %d"), *SessionName.ToString(), bWasSuccessful));
UE_LOG(LogTemp, Verbose, TEXT("OnDestroySessionComplete()"));
// Get the OnlineSubsystem we want to work with
IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get();
if (OnlineSub)
{
// Get the SessionInterface from the OnlineSubsystem
IOnlineSessionPtr OculusSessionInterface = OnlineSub->GetSessionInterface();
if (OculusSessionInterface.IsValid())
{
// Clear the Delegate
OculusSessionInterface->ClearOnDestroySessionCompleteDelegate_Handle(OnDestroySessionCompleteDelegateHandle);
if (bWasSuccessful)
{
//check if there is a pending invite and attempt to join the invited session if so
if (!AcceptedInviteFrom.IsEmpty())
{
UE_LOG(LogTemp, Verbose, TEXT("Found a pending invite and trying to join %s's game"), *AcceptedInviteFrom);
OnJoinSessionCompleteDelegateHandle = OculusSessionInterface->AddOnJoinSessionCompleteDelegate_Handle(OnJoinSessionCompleteDelegate);
OculusSessionInterface->JoinSession(0, FName(*AcceptedInviteFrom), AcceptedInvite);
AcceptedInviteFrom.Empty();
}
UE_LOG(LogTemp, Verbose, TEXT("Destroy Session success"));
//close the VoIP channel when leaving the session.
Online::GetVoiceInterface()->StopNetworkedVoice(0);
Online::GetVoiceInterface()->RemoveAllRemoteTalkers();
}
else
{
UE_LOG(LogTemp, Verbose, TEXT("Destroy Session fail"));
}
}
}
}
void AOculusOSS::RichPresenceOptions_Destroy()
{
UE_LOG(LogTemp, Verbose, TEXT("RichPresenceOptions_Destroy"));
ovr_RichPresenceOptions_Destroy(ovr_RichPresenceOptions_Handle);
}
void AOculusOSS::SetRichPresenceAPIName(FString RichPresenceAPIName)
{
UE_LOG(LogTemp, Verbose, TEXT("SetRichPresenceAPIName"));
ovr_RichPresenceOptions_SetApiName(ovr_RichPresenceOptions_Handle, TCHAR_TO_ANSI(*RichPresenceAPIName));
}
void AOculusOSS::SetRichPresenceArgsString(FString RichPresenceArgsKey, FString RichPresenceArgsValue)
{
UE_LOG(LogTemp, Verbose, TEXT("SetRichPresenceArgsString"));
ovr_RichPresenceOptions_SetArgsString(ovr_RichPresenceOptions_Handle, TCHAR_TO_ANSI(*RichPresenceArgsKey), TCHAR_TO_ANSI(*RichPresenceArgsValue));
}
void AOculusOSS::RichPresenceClearArgs()
{
UE_LOG(LogTemp, Verbose, TEXT("RichPresenceClearArgs"));
ovr_RichPresenceOptions_ClearArgs(ovr_RichPresenceOptions_Handle);
}
void AOculusOSS::SetRichPresenceCurrentCapacity(uint8 CurrentCapacity)
{
UE_LOG(LogTemp, Verbose, TEXT("SetRichPresenceCurrentCapacity"));
ovr_RichPresenceOptions_SetCurrentCapacity(ovr_RichPresenceOptions_Handle, CurrentCapacity);
}
void AOculusOSS::SetRichPresenceDeeplinkMessageOverride(FString DeeplinkMessageOverride)
{
UE_LOG(LogTemp, Verbose, TEXT("SetRichPresenceDeeplinkMessageOverride"));
ovr_RichPresenceOptions_SetDeeplinkMessageOverride(ovr_RichPresenceOptions_Handle, TCHAR_TO_ANSI(*DeeplinkMessageOverride));
}
void AOculusOSS::SetRichPresenceSetEndTime(FString EndTime)
{
UE_LOG(LogTemp, Verbose, TEXT("SetRichPresenceSetEndTime"));
ovr_RichPresenceOptions_SetEndTime(ovr_RichPresenceOptions_Handle, FCString::Atoi64(*EndTime));
}
void AOculusOSS::SetRichPresenceIsIdle(bool IsIdle)
{
UE_LOG(LogTemp, Verbose, TEXT("SetRichPresenceIsIdle"));
ovr_RichPresenceOptions_SetIsIdle(ovr_RichPresenceOptions_Handle, IsIdle);
}
void AOculusOSS::SetRichPresenceIsJoinable(bool IsJoinable)
{
UE_LOG(LogTemp, Verbose, TEXT("SetRichPresenceIsJoinable"));
ovr_RichPresenceOptions_SetIsJoinable(ovr_RichPresenceOptions_Handle, IsJoinable);
}
void AOculusOSS::SetRichPresenceJoinableId(FString JoinableId)
{
UE_LOG(LogTemp, Verbose, TEXT("SetRichPresenceJoinableId"));
ovr_RichPresenceOptions_SetJoinableId(ovr_RichPresenceOptions_Handle, TCHAR_TO_ANSI(*JoinableId));
}
void AOculusOSS::SetRichPresenceMaxCapacity(uint8 MaxCapacity)
{
UE_LOG(LogTemp, Verbose, TEXT("SetRichPresenceMaxCapacity"));
ovr_RichPresenceOptions_SetMaxCapacity(ovr_RichPresenceOptions_Handle, MaxCapacity);
}
void AOculusOSS::SetRichPresenceStartTime(FString StartTime)
{
UE_LOG(LogTemp, Verbose, TEXT("SetRichPresenceStartTime"));
ovr_RichPresenceOptions_SetStartTime(ovr_RichPresenceOptions_Handle, FCString::Atoi64(*StartTime));
}
GameName.exe -mixedreality
adb shell "am broadcast -a android.intent.action.RUN -e cmd 'stat unit'"