Up to Unreal 5.7
This commit is contained in:
parent
8a63902c06
commit
1a64805d43
239 changed files with 3947 additions and 296 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -4,3 +4,6 @@
|
||||||
[submodule "VIRTUOS_ExpansionPluginTests/Plugins/StevesUEHelpers"]
|
[submodule "VIRTUOS_ExpansionPluginTests/Plugins/StevesUEHelpers"]
|
||||||
path = VIRTUOS_ExpansionPluginTests/Plugins/StevesUEHelpers
|
path = VIRTUOS_ExpansionPluginTests/Plugins/StevesUEHelpers
|
||||||
url = https://github.com/sinbad/StevesUEHelpers
|
url = https://github.com/sinbad/StevesUEHelpers
|
||||||
|
[submodule "VIRTUOS_ExpansionPluginTests/Plugins/VRExpansionPlugin"]
|
||||||
|
path = VIRTUOS_ExpansionPluginTests/Plugins/VRExpansionPlugin
|
||||||
|
url = https://github.com/mordentral/VRExpansionPlugin
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
"Microsoft.Net.Component.4.6.2.TargetingPack",
|
"Microsoft.Net.Component.4.6.2.TargetingPack",
|
||||||
"Microsoft.VisualStudio.Component.VC.14.38.17.8.ATL",
|
"Microsoft.VisualStudio.Component.VC.14.38.17.8.ATL",
|
||||||
"Microsoft.VisualStudio.Component.VC.14.38.17.8.x86.x64",
|
"Microsoft.VisualStudio.Component.VC.14.38.17.8.x86.x64",
|
||||||
|
"Microsoft.VisualStudio.Component.VC.14.44.17.14.ATL",
|
||||||
|
"Microsoft.VisualStudio.Component.VC.14.44.17.14.x86.x64",
|
||||||
"Microsoft.VisualStudio.Component.VC.Llvm.Clang",
|
"Microsoft.VisualStudio.Component.VC.Llvm.Clang",
|
||||||
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
|
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
|
||||||
"Microsoft.VisualStudio.Component.Windows11SDK.22621",
|
"Microsoft.VisualStudio.Component.Windows11SDK.22621",
|
||||||
|
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
* text=auto
|
|
||||||
*.bat eol=crlf
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
|
|
||||||
.hg/
|
|
||||||
binaries/
|
|
||||||
deriveddatacache/
|
|
||||||
.vs/
|
|
||||||
build/
|
|
||||||
intermediate/
|
|
||||||
PACKPLUGIN/
|
|
||||||
saved/
|
|
||||||
*.orig
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
"FileVersion": 3,
|
"FileVersion": 3,
|
||||||
"FriendlyName": "Advanced Sessions",
|
"FriendlyName": "Advanced Sessions",
|
||||||
"Version": 5.4,
|
"Version": 5.7,
|
||||||
"VersionName": "5.4",
|
"VersionName": "5.7",
|
||||||
"Description": "Adds new blueprint functions to handle more advanced session operations.",
|
"Description": "Adds new blueprint functions to handle more advanced session operations.",
|
||||||
"Category": "Advanced Sessions Plugin",
|
"Category": "Advanced Sessions Plugin",
|
||||||
"CreatedBy": "Joshua Statzer",
|
"CreatedBy": "Joshua Statzer",
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
Copyright Joshua Statzer
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
### How do I use it? ###
|
|
||||||
|
|
||||||
**KantanDocGen Automatic Documentation ([KantanDocGen](http://kantandev.com/free/kantan-doc-gen))**
|
|
||||||
|
|
||||||
**[AdvancedSessions](https://vreue4.com/generated-node-documentation?section=advanced-sessions-plugin)**
|
|
||||||
|
|
||||||
**[AdvancedSteamSessions](https://vreue4.com/generated-node-documentation?section=advanced-steam-sessions-plugin)**
|
|
||||||
|
|
@ -5,6 +5,9 @@ public class AdvancedSessions : ModuleRules
|
||||||
{
|
{
|
||||||
public AdvancedSessions(ReadOnlyTargetRules Target) : base(Target)
|
public AdvancedSessions(ReadOnlyTargetRules Target) : base(Target)
|
||||||
{
|
{
|
||||||
|
DefaultBuildSettings = BuildSettingsVersion.Latest;
|
||||||
|
IncludeOrderVersion = EngineIncludeOrderVersion.Latest;
|
||||||
|
|
||||||
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||||
//bEnforceIWYU = true;
|
//bEnforceIWYU = true;
|
||||||
|
|
||||||
|
|
@ -44,6 +44,16 @@ public:
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AdvancedVoiceInterface)
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AdvancedVoiceInterface)
|
||||||
bool bEnableTalkingStatusDelegate;
|
bool bEnableTalkingStatusDelegate;
|
||||||
|
|
||||||
|
// If true we will auto join a session we have accepted in the overlay.
|
||||||
|
// This can get in the way of Beacon Sessions, you may want to disable it.
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AdvancedFriendsInterface)
|
||||||
|
bool bAutoJoinSessionOnAcceptedUserInviteReceived = false;
|
||||||
|
|
||||||
|
// If true we will auto travel to a game session when an invite is received.
|
||||||
|
// This can get in the way of Beacon Sessions, you may want to disable it.
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AdvancedFriendsInterface)
|
||||||
|
bool bAutoTravelOnAcceptedUserInviteReceived = false;
|
||||||
|
|
||||||
//virtual void PostLoad() override;
|
//virtual void PostLoad() override;
|
||||||
virtual void Shutdown() override;
|
virtual void Shutdown() override;
|
||||||
virtual void Init() override;
|
virtual void Init() override;
|
||||||
|
|
@ -52,6 +62,13 @@ public:
|
||||||
FOnSessionInviteReceivedDelegate SessionInviteReceivedDelegate;
|
FOnSessionInviteReceivedDelegate SessionInviteReceivedDelegate;
|
||||||
FDelegateHandle SessionInviteReceivedDelegateHandle;
|
FDelegateHandle SessionInviteReceivedDelegateHandle;
|
||||||
|
|
||||||
|
// custom handle to join directly from steam ui "Join Game"
|
||||||
|
FDelegateHandle OnJoinSessionCompleteDelegateHandle;
|
||||||
|
// custom Steam UI Join User function #Self invite#
|
||||||
|
void OnSessionUserInviteAccepted(const bool bWasSuccessful, const int32 ControllerId, FUniqueNetIdPtr UserId, const FOnlineSessionSearchResult& InviteResult);
|
||||||
|
// custom Steam UI function to client travel #Self invite#
|
||||||
|
void OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result);
|
||||||
|
|
||||||
//const FUniqueNetId& /*UserId*/, const FUniqueNetId& /*FromId*/, const FString& /*AppId*/, const FOnlineSessionSearchResult& /*InviteResult*/
|
//const FUniqueNetId& /*UserId*/, const FUniqueNetId& /*FromId*/, const FString& /*AppId*/, const FOnlineSessionSearchResult& /*InviteResult*/
|
||||||
void OnSessionInviteReceivedMaster(const FUniqueNetId & PersonInvited, const FUniqueNetId & PersonInviting, const FString & AppId, const FOnlineSessionSearchResult& SessionToJoin);
|
void OnSessionInviteReceivedMaster(const FUniqueNetId & PersonInvited, const FUniqueNetId & PersonInviting, const FString & AppId, const FOnlineSessionSearchResult& SessionToJoin);
|
||||||
|
|
||||||
|
|
@ -160,6 +160,10 @@ public:
|
||||||
UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|PlayerInfo|PlayerID")
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|PlayerInfo|PlayerID")
|
||||||
static void GetUniqueNetID(APlayerController *PlayerController, FBPUniqueNetId &UniqueNetId);
|
static void GetUniqueNetID(APlayerController *PlayerController, FBPUniqueNetId &UniqueNetId);
|
||||||
|
|
||||||
|
// Get the unique net id of a network player attached to the given controller
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|PlayerInfo|PlayerID")
|
||||||
|
static void GetUniqueNetIdOfSessionOwner(FBlueprintSessionResult SessionResult, FBPUniqueNetId& UniqueNetId);
|
||||||
|
|
||||||
// Get the unique net id of a network player who is assigned the the given player state
|
// Get the unique net id of a network player who is assigned the the given player state
|
||||||
UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|PlayerInfo|PlayerID")
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|PlayerInfo|PlayerID")
|
||||||
static void GetUniqueNetIDFromPlayerState(APlayerState *PlayerState, FBPUniqueNetId &UniqueNetId);
|
static void GetUniqueNetIDFromPlayerState(APlayerState *PlayerState, FBPUniqueNetId &UniqueNetId);
|
||||||
|
|
@ -23,14 +23,14 @@ class UCreateSessionCallbackProxyAdvanced : public UOnlineBlueprintCallProxyBase
|
||||||
* Creates a session with the default online subsystem with advanced optional inputs, for dedicated servers leave UsePresence as false and set IsDedicatedServer to true. Dedicated servers don't use presence.
|
* Creates a session with the default online subsystem with advanced optional inputs, for dedicated servers leave UsePresence as false and set IsDedicatedServer to true. Dedicated servers don't use presence.
|
||||||
* @param PublicConnections When doing a 'listen' server, this must be >=2 (ListenServer itself counts as a connection)
|
* @param PublicConnections When doing a 'listen' server, this must be >=2 (ListenServer itself counts as a connection)
|
||||||
* @param bUseLAN When you want to play LAN, the level to play on must be loaded with option 'bIsLanMatch'
|
* @param bUseLAN When you want to play LAN, the level to play on must be loaded with option 'bIsLanMatch'
|
||||||
* @param bUsePresence Must be true for a 'listen' server (Map must be loaded with option 'listen'), false for a 'dedicated' server.
|
|
||||||
* @param bUseLobbiesIfAvailable Used to flag the subsystem to use a lobby api instead of general hosting if the API supports it, generally true on steam for listen servers and false for dedicated
|
* @param bUseLobbiesIfAvailable Used to flag the subsystem to use a lobby api instead of general hosting if the API supports it, generally true on steam for listen servers and false for dedicated
|
||||||
|
* Must be true for a 'listen' server (Map must be loaded with option 'listen'), false for a 'dedicated' server.
|
||||||
* @param bShouldAdvertise Set to true when the OnlineSubsystem should list your server when someone is searching for servers. Otherwise the server is hidden and only join via invite is possible.
|
* @param bShouldAdvertise Set to true when the OnlineSubsystem should list your server when someone is searching for servers. Otherwise the server is hidden and only join via invite is possible.
|
||||||
* @param bUseLobbiesVoiceChatIfAvailable Set to true to setup voice chat lobbies if the API supports it
|
* @param bUseLobbiesVoiceChatIfAvailable Set to true to setup voice chat lobbies if the API supports it
|
||||||
* @param bStartAfterCreate Set to true to start the session after it's created. If false you need to manually call StartSession when ready.
|
* @param bStartAfterCreate Set to true to start the session after it's created. If false you need to manually call StartSession when ready.
|
||||||
*/
|
*/
|
||||||
UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject",AutoCreateRefTerm="ExtraSettings"), Category = "Online|AdvancedSessions")
|
UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject",AutoCreateRefTerm="ExtraSettings"), Category = "Online|AdvancedSessions")
|
||||||
static UCreateSessionCallbackProxyAdvanced* CreateAdvancedSession(UObject* WorldContextObject, const TArray<FSessionPropertyKeyPair>& ExtraSettings, class APlayerController* PlayerController = NULL, int32 PublicConnections = 100, int32 PrivateConnections = 0, bool bUseLAN = false, bool bAllowInvites = true, bool bIsDedicatedServer = false, bool bUsePresence = true, bool bUseLobbiesIfAvailable = true, bool bAllowJoinViaPresence = true, bool bAllowJoinViaPresenceFriendsOnly = false, bool bAntiCheatProtected = false, bool bUsesStats = false, bool bShouldAdvertise = true, bool bUseLobbiesVoiceChatIfAvailable = false, bool bStartAfterCreate = true);
|
static UCreateSessionCallbackProxyAdvanced* CreateAdvancedSession(UObject* WorldContextObject, const TArray<FSessionPropertyKeyPair>& ExtraSettings, class APlayerController* PlayerController = NULL, int32 PublicConnections = 100, int32 PrivateConnections = 0, bool bUseLAN = false, bool bAllowInvites = true, bool bIsDedicatedServer = false, /*bool bUsePresence = true,*/ bool bUseLobbiesIfAvailable = true, bool bAllowJoinViaPresence = true, bool bAllowJoinViaPresenceFriendsOnly = false, bool bAntiCheatProtected = false, bool bUsesStats = false, bool bShouldAdvertise = true, bool bUseLobbiesVoiceChatIfAvailable = false, bool bStartAfterCreate = true);
|
||||||
|
|
||||||
// UOnlineBlueprintCallProxyBase interface
|
// UOnlineBlueprintCallProxyBase interface
|
||||||
virtual void Activate() override;
|
virtual void Activate() override;
|
||||||
|
|
@ -28,7 +28,7 @@ class UFindSessionsCallbackProxyAdvanced : public UOnlineBlueprintCallProxyBase
|
||||||
|
|
||||||
// Searches for advertised sessions with the default online subsystem and includes an array of filters
|
// Searches for advertised sessions with the default online subsystem and includes an array of filters
|
||||||
UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true", WorldContext = "WorldContextObject", AutoCreateRefTerm="Filters"), Category = "Online|AdvancedSessions")
|
UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true", WorldContext = "WorldContextObject", AutoCreateRefTerm="Filters"), Category = "Online|AdvancedSessions")
|
||||||
static UFindSessionsCallbackProxyAdvanced* FindSessionsAdvanced(UObject* WorldContextObject, class APlayerController* PlayerController, int32 MaxResults, bool bUseLAN, EBPServerPresenceSearchType ServerTypeToSearch, const TArray<FSessionsSearchSetting> &Filters, bool bEmptyServersOnly = false, bool bNonEmptyServersOnly = false, bool bSecureServersOnly = false, bool bSearchLobbies = true, int MinSlotsAvailable = 0);
|
static UFindSessionsCallbackProxyAdvanced* FindSessionsAdvanced(UObject* WorldContextObject, class APlayerController* PlayerController, int32 MaxResults, bool bUseLAN, EBPServerPresenceSearchType ServerTypeToSearch, const TArray<FSessionsSearchSetting> &Filters, bool bEmptyServersOnly = false, bool bNonEmptyServersOnly = false, bool bSecureServersOnly = false, /*bool bSearchLobbies = true,*/ int MinSlotsAvailable = 0);
|
||||||
|
|
||||||
static bool CompareVariants(const FVariantData &A, const FVariantData &B, EOnlineComparisonOpRedux Comparator);
|
static bool CompareVariants(const FVariantData &A, const FVariantData &B, EOnlineComparisonOpRedux Comparator);
|
||||||
|
|
||||||
|
|
@ -99,7 +99,7 @@ private:
|
||||||
bool bSecureServersOnly;
|
bool bSecureServersOnly;
|
||||||
|
|
||||||
// Search through lobbies
|
// Search through lobbies
|
||||||
bool bSearchLobbies;
|
//bool bSearchLobbies;
|
||||||
|
|
||||||
// Min slots requires to search
|
// Min slots requires to search
|
||||||
int MinSlotsAvailable;
|
int MinSlotsAvailable;
|
||||||
|
|
@ -21,7 +21,7 @@ class UUpdateSessionCallbackProxyAdvanced : public UOnlineBlueprintCallProxyBase
|
||||||
|
|
||||||
// Creates a session with the default online subsystem with advanced optional inputs, you MUST fill in all categories or it will pass in values that you didn't want as default values
|
// Creates a session with the default online subsystem with advanced optional inputs, you MUST fill in all categories or it will pass in values that you didn't want as default values
|
||||||
UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject",AutoCreateRefTerm="ExtraSettings"), Category = "Online|AdvancedSessions")
|
UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject",AutoCreateRefTerm="ExtraSettings"), Category = "Online|AdvancedSessions")
|
||||||
static UUpdateSessionCallbackProxyAdvanced* UpdateSession(UObject* WorldContextObject, const TArray<FSessionPropertyKeyPair> &ExtraSettings, int32 PublicConnections = 100, int32 PrivateConnections = 0, bool bUseLAN = false, bool bAllowInvites = false, bool bAllowJoinInProgress = false, bool bRefreshOnlineData = true, bool bIsDedicatedServer = false, bool bShouldAdvertise = true);
|
static UUpdateSessionCallbackProxyAdvanced* UpdateSession(UObject* WorldContextObject, const TArray<FSessionPropertyKeyPair> &ExtraSettings, int32 PublicConnections = 100, int32 PrivateConnections = 0, bool bUseLAN = false, bool bAllowInvites = false, bool bAllowJoinInProgress = false, bool bRefreshOnlineData = true, bool bIsDedicatedServer = false, bool bShouldAdvertise = true, bool bAllowJoinViaPresence = true, bool bAllowJoinViaPresenceFriendsOnly = false);
|
||||||
|
|
||||||
// UOnlineBlueprintCallProxyBase interface
|
// UOnlineBlueprintCallProxyBase interface
|
||||||
virtual void Activate() override;
|
virtual void Activate() override;
|
||||||
|
|
@ -58,6 +58,12 @@ private:
|
||||||
// Allow joining in progress
|
// Allow joining in progress
|
||||||
bool bAllowJoinInProgress = true;
|
bool bAllowJoinInProgress = true;
|
||||||
|
|
||||||
|
// Allow joining in progress
|
||||||
|
bool bAllowJoinViaPresence = true;
|
||||||
|
|
||||||
|
// Allow joining in progress
|
||||||
|
bool bAllowJoinViaPresenceFriendsOnly = false;
|
||||||
|
|
||||||
// Update whether this is a dedicated server or not
|
// Update whether this is a dedicated server or not
|
||||||
bool bDedicatedServer = false;
|
bool bDedicatedServer = false;
|
||||||
|
|
||||||
|
|
@ -20,6 +20,61 @@ UAdvancedFriendsGameInstance::UAdvancedFriendsGameInstance(const FObjectInitiali
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UAdvancedFriendsGameInstance::OnSessionUserInviteAccepted(const bool bWasSuccessful, const int32 ControllerId, FUniqueNetIdPtr UserId, const FOnlineSessionSearchResult& InviteResult)
|
||||||
|
{
|
||||||
|
if (!bAutoJoinSessionOnAcceptedUserInviteReceived)
|
||||||
|
return;
|
||||||
|
|
||||||
|
IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
||||||
|
if (SessionInterface.IsValid())
|
||||||
|
{
|
||||||
|
// Eventually call this?, would need another call back to run through
|
||||||
|
//SessionInterface->DestroySession(NAME_GameSession);
|
||||||
|
|
||||||
|
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(OnJoinSessionCompleteDelegateHandle);
|
||||||
|
OnJoinSessionCompleteDelegateHandle = SessionInterface->AddOnJoinSessionCompleteDelegate_Handle(
|
||||||
|
FOnJoinSessionCompleteDelegate::CreateUObject(this, &UAdvancedFriendsGameInstance::OnJoinSessionComplete));
|
||||||
|
|
||||||
|
// Temp for 5.5, they aren't filling in the struct correctly
|
||||||
|
if (!InviteResult.Session.SessionSettings.bIsDedicated)
|
||||||
|
{
|
||||||
|
FOnlineSessionSearchResult ModResult = InviteResult;
|
||||||
|
ModResult.Session.SessionSettings.bUsesPresence = true;
|
||||||
|
ModResult.Session.SessionSettings.bUseLobbiesIfAvailable = true;
|
||||||
|
SessionInterface->JoinSession(0, NAME_GameSession, ModResult);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SessionInterface->JoinSession(0, NAME_GameSession, InviteResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UE_LOG(AdvancedFriendsInterfaceLog, Log, TEXT("Called Join Session for Steam Friends List UI InviteResults: %s, UserId: %s"), *InviteResult.GetSessionIdStr(), *UserId->ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedFriendsGameInstance::OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result)
|
||||||
|
{
|
||||||
|
|
||||||
|
// If we don't want to auto travel to the session instance then exit out
|
||||||
|
if (!bAutoTravelOnAcceptedUserInviteReceived)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
||||||
|
if (SessionInterface.IsValid())
|
||||||
|
{
|
||||||
|
FString ConnectInfo;
|
||||||
|
if (SessionInterface->GetResolvedConnectString(NAME_GameSession, ConnectInfo))
|
||||||
|
{
|
||||||
|
APlayerController* PlayerController = GetFirstLocalPlayerController();
|
||||||
|
if (PlayerController)
|
||||||
|
{
|
||||||
|
PlayerController->ClientTravel(ConnectInfo, ETravelType::TRAVEL_Absolute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void UAdvancedFriendsGameInstance::Shutdown()
|
void UAdvancedFriendsGameInstance::Shutdown()
|
||||||
{
|
{
|
||||||
IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
||||||
|
|
@ -34,6 +89,7 @@ void UAdvancedFriendsGameInstance::Shutdown()
|
||||||
// Clear all of the delegate handles here
|
// Clear all of the delegate handles here
|
||||||
SessionInterface->ClearOnSessionUserInviteAcceptedDelegate_Handle(SessionInviteAcceptedDelegateHandle);
|
SessionInterface->ClearOnSessionUserInviteAcceptedDelegate_Handle(SessionInviteAcceptedDelegateHandle);
|
||||||
SessionInterface->ClearOnSessionInviteReceivedDelegate_Handle(SessionInviteReceivedDelegateHandle);
|
SessionInterface->ClearOnSessionInviteReceivedDelegate_Handle(SessionInviteReceivedDelegateHandle);
|
||||||
|
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(OnJoinSessionCompleteDelegateHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -80,6 +136,9 @@ void UAdvancedFriendsGameInstance::Init()
|
||||||
SessionInviteAcceptedDelegateHandle = SessionInterface->AddOnSessionUserInviteAcceptedDelegate_Handle(SessionInviteAcceptedDelegate);
|
SessionInviteAcceptedDelegateHandle = SessionInterface->AddOnSessionUserInviteAcceptedDelegate_Handle(SessionInviteAcceptedDelegate);
|
||||||
|
|
||||||
SessionInviteReceivedDelegateHandle = SessionInterface->AddOnSessionInviteReceivedDelegate_Handle(SessionInviteReceivedDelegate);
|
SessionInviteReceivedDelegateHandle = SessionInterface->AddOnSessionInviteReceivedDelegate_Handle(SessionInviteReceivedDelegate);
|
||||||
|
|
||||||
|
// Custom steam join game delegate
|
||||||
|
SessionInterface->OnSessionUserInviteAcceptedDelegates.AddUObject(this, &UAdvancedFriendsGameInstance::OnSessionUserInviteAccepted);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -271,6 +330,13 @@ void UAdvancedFriendsGameInstance::OnSessionInviteReceivedMaster(const FUniqueNe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Temp for 5.5, they aren't filling in the struct correctly
|
||||||
|
if (!BluePrintResult.OnlineResult.Session.SessionSettings.bIsDedicated)
|
||||||
|
{
|
||||||
|
BluePrintResult.OnlineResult.Session.SessionSettings.bUsesPresence = true;
|
||||||
|
BluePrintResult.OnlineResult.Session.SessionSettings.bUseLobbiesIfAvailable = true;
|
||||||
|
}
|
||||||
|
|
||||||
OnSessionInviteReceived(LocalPlayer, PInviting, AppId, BluePrintResult);
|
OnSessionInviteReceived(LocalPlayer, PInviting, AppId, BluePrintResult);
|
||||||
|
|
||||||
//IAdvancedFriendsInterface* TheInterface = NULL;
|
//IAdvancedFriendsInterface* TheInterface = NULL;
|
||||||
|
|
@ -307,6 +373,13 @@ void UAdvancedFriendsGameInstance::OnSessionInviteAcceptedMaster(const bool bWas
|
||||||
FBPUniqueNetId PInvited;
|
FBPUniqueNetId PInvited;
|
||||||
PInvited.SetUniqueNetId(PersonInvited);
|
PInvited.SetUniqueNetId(PersonInvited);
|
||||||
|
|
||||||
|
// Temp for 5.5, they aren't filling in the struct correctly
|
||||||
|
if (!BluePrintResult.OnlineResult.Session.SessionSettings.bIsDedicated)
|
||||||
|
{
|
||||||
|
BluePrintResult.OnlineResult.Session.SessionSettings.bUsesPresence = true;
|
||||||
|
BluePrintResult.OnlineResult.Session.SessionSettings.bUseLobbiesIfAvailable = true;
|
||||||
|
}
|
||||||
|
|
||||||
OnSessionInviteAccepted(LocalPlayer,PInvited, BluePrintResult);
|
OnSessionInviteAccepted(LocalPlayer,PInvited, BluePrintResult);
|
||||||
|
|
||||||
APlayerController* Player = UGameplayStatics::GetPlayerController(GetWorld(), LocalPlayer);
|
APlayerController* Player = UGameplayStatics::GetPlayerController(GetWorld(), LocalPlayer);
|
||||||
|
|
@ -151,7 +151,9 @@ void UAdvancedFriendsLibrary::GetFriend(APlayerController *PlayerController, con
|
||||||
Friend.PresenceInfo.bIsPlaying = pres.bIsPlaying;
|
Friend.PresenceInfo.bIsPlaying = pres.bIsPlaying;
|
||||||
Friend.PresenceInfo.bIsPlayingThisGame = pres.bIsPlayingThisGame;
|
Friend.PresenceInfo.bIsPlayingThisGame = pres.bIsPlayingThisGame;
|
||||||
Friend.PresenceInfo.PresenceState = ((EBPOnlinePresenceState)((int32)pres.Status.State));
|
Friend.PresenceInfo.PresenceState = ((EBPOnlinePresenceState)((int32)pres.Status.State));
|
||||||
|
|
||||||
// #TODO: Check back in on this in shipping, epic is missing the UTF8_TO_TCHAR call on converting this and its making an invalid string
|
// #TODO: Check back in on this in shipping, epic is missing the UTF8_TO_TCHAR call on converting this and its making an invalid string
|
||||||
|
// OnlineFriendPresenceInterfaceSteam has the issue
|
||||||
//Friend.PresenceInfo.StatusString = pres.Status.StatusStr;
|
//Friend.PresenceInfo.StatusString = pres.Status.StatusStr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -266,6 +268,7 @@ void UAdvancedFriendsLibrary::GetStoredFriendsList(APlayerController *PlayerCont
|
||||||
BPF.PresenceInfo.bIsPlaying = pres.bIsPlaying;
|
BPF.PresenceInfo.bIsPlaying = pres.bIsPlaying;
|
||||||
BPF.PresenceInfo.PresenceState = ((EBPOnlinePresenceState)((int32)pres.Status.State));
|
BPF.PresenceInfo.PresenceState = ((EBPOnlinePresenceState)((int32)pres.Status.State));
|
||||||
// #TODO: Check back in on this in shipping, epic is missing the UTF8_TO_TCHAR call on converting this and its making an invalid string
|
// #TODO: Check back in on this in shipping, epic is missing the UTF8_TO_TCHAR call on converting this and its making an invalid string
|
||||||
|
// OnlineFriendPresenceInterfaceSteam has the issue
|
||||||
//BPF.PresenceInfo.StatusString = pres.Status.StatusStr;
|
//BPF.PresenceInfo.StatusString = pres.Status.StatusStr;
|
||||||
BPF.PresenceInfo.bIsJoinable = pres.bIsJoinable;
|
BPF.PresenceInfo.bIsJoinable = pres.bIsJoinable;
|
||||||
BPF.PresenceInfo.bIsPlayingThisGame = pres.bIsPlayingThisGame;
|
BPF.PresenceInfo.bIsPlayingThisGame = pres.bIsPlayingThisGame;
|
||||||
|
|
@ -451,6 +451,17 @@ void UAdvancedSessionsLibrary::GetUniqueNetID(APlayerController *PlayerControlle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UAdvancedSessionsLibrary::GetUniqueNetIdOfSessionOwner(FBlueprintSessionResult SessionResult, FBPUniqueNetId& UniqueNetId)
|
||||||
|
{
|
||||||
|
FBPUniqueNetId ReturnID;
|
||||||
|
if (SessionResult.OnlineResult.IsValid())
|
||||||
|
{
|
||||||
|
ReturnID.SetUniqueNetId(SessionResult.OnlineResult.Session.OwningUserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
UniqueNetId = ReturnID;
|
||||||
|
}
|
||||||
|
|
||||||
void UAdvancedSessionsLibrary::GetUniqueNetIDFromPlayerState(APlayerState *PlayerState, FBPUniqueNetId &UniqueNetId)
|
void UAdvancedSessionsLibrary::GetUniqueNetIDFromPlayerState(APlayerState *PlayerState, FBPUniqueNetId &UniqueNetId)
|
||||||
{
|
{
|
||||||
if (!PlayerState)
|
if (!PlayerState)
|
||||||
|
|
@ -83,6 +83,8 @@ void UAutoLoginUserCallbackProxy::OnCompleted(int32 LocalUserNum, bool bWasSucce
|
||||||
{
|
{
|
||||||
OnFailure.Broadcast();
|
OnFailure.Broadcast();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OnFailure.Broadcast();
|
OnFailure.Broadcast();
|
||||||
|
|
@ -13,7 +13,7 @@ UCreateSessionCallbackProxyAdvanced::UCreateSessionCallbackProxyAdvanced(const F
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
UCreateSessionCallbackProxyAdvanced* UCreateSessionCallbackProxyAdvanced::CreateAdvancedSession(UObject* WorldContextObject, const TArray<FSessionPropertyKeyPair>& ExtraSettings, class APlayerController* PlayerController, int32 PublicConnections, int32 PrivateConnections, bool bUseLAN, bool bAllowInvites, bool bIsDedicatedServer, bool bUsePresence, bool bUseLobbiesIfAvailable, bool bAllowJoinViaPresence, bool bAllowJoinViaPresenceFriendsOnly, bool bAntiCheatProtected, bool bUsesStats, bool bShouldAdvertise, bool bUseLobbiesVoiceChatIfAvailable, bool bStartAfterCreate)
|
UCreateSessionCallbackProxyAdvanced* UCreateSessionCallbackProxyAdvanced::CreateAdvancedSession(UObject* WorldContextObject, const TArray<FSessionPropertyKeyPair>& ExtraSettings, class APlayerController* PlayerController, int32 PublicConnections, int32 PrivateConnections, bool bUseLAN, bool bAllowInvites, bool bIsDedicatedServer, /*bool bUsePresence,*/ bool bUseLobbiesIfAvailable, bool bAllowJoinViaPresence, bool bAllowJoinViaPresenceFriendsOnly, bool bAntiCheatProtected, bool bUsesStats, bool bShouldAdvertise, bool bUseLobbiesVoiceChatIfAvailable, bool bStartAfterCreate)
|
||||||
{
|
{
|
||||||
UCreateSessionCallbackProxyAdvanced* Proxy = NewObject<UCreateSessionCallbackProxyAdvanced>();
|
UCreateSessionCallbackProxyAdvanced* Proxy = NewObject<UCreateSessionCallbackProxyAdvanced>();
|
||||||
Proxy->PlayerControllerWeakPtr = PlayerController;
|
Proxy->PlayerControllerWeakPtr = PlayerController;
|
||||||
|
|
@ -24,7 +24,7 @@ UCreateSessionCallbackProxyAdvanced* UCreateSessionCallbackProxyAdvanced::Create
|
||||||
Proxy->bAllowInvites = bAllowInvites;
|
Proxy->bAllowInvites = bAllowInvites;
|
||||||
Proxy->ExtraSettings = ExtraSettings;
|
Proxy->ExtraSettings = ExtraSettings;
|
||||||
Proxy->bDedicatedServer = bIsDedicatedServer;
|
Proxy->bDedicatedServer = bIsDedicatedServer;
|
||||||
Proxy->bUsePresence = bUsePresence;
|
/*Proxy->bUsePresence = bUsePresence;*/
|
||||||
Proxy->bUseLobbiesIfAvailable = bUseLobbiesIfAvailable;
|
Proxy->bUseLobbiesIfAvailable = bUseLobbiesIfAvailable;
|
||||||
Proxy->bAllowJoinViaPresence = bAllowJoinViaPresence;
|
Proxy->bAllowJoinViaPresence = bAllowJoinViaPresence;
|
||||||
Proxy->bAllowJoinViaPresenceFriendsOnly = bAllowJoinViaPresenceFriendsOnly;
|
Proxy->bAllowJoinViaPresenceFriendsOnly = bAllowJoinViaPresenceFriendsOnly;
|
||||||
|
|
@ -61,13 +61,13 @@ void UCreateSessionCallbackProxyAdvanced::Activate()
|
||||||
|
|
||||||
if (bDedicatedServer)
|
if (bDedicatedServer)
|
||||||
{
|
{
|
||||||
Settings.bUsesPresence = false;
|
|
||||||
Settings.bUseLobbiesIfAvailable = false;
|
Settings.bUseLobbiesIfAvailable = false;
|
||||||
|
Settings.bUsesPresence = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Settings.bUsesPresence = bUsePresence;
|
|
||||||
Settings.bUseLobbiesIfAvailable = bUseLobbiesIfAvailable;
|
Settings.bUseLobbiesIfAvailable = bUseLobbiesIfAvailable;
|
||||||
|
Settings.bUsesPresence = bUseLobbiesIfAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings.bUseLobbiesVoiceChatIfAvailable = bUseLobbiesIfAvailable ? bUseLobbiesVoiceChatIfAvailable : false;
|
Settings.bUseLobbiesVoiceChatIfAvailable = bUseLobbiesIfAvailable ? bUseLobbiesVoiceChatIfAvailable : false;
|
||||||
|
|
@ -102,6 +102,14 @@ void UFindFriendSessionCallbackProxy::OnFindFriendSessionCompleted(int32 LocalPl
|
||||||
{
|
{
|
||||||
FBlueprintSessionResult BSesh;
|
FBlueprintSessionResult BSesh;
|
||||||
BSesh.OnlineResult = Sesh;
|
BSesh.OnlineResult = Sesh;
|
||||||
|
|
||||||
|
// Temp for 5.5, force the values if epic isn't setting them, lobbies should always have these true
|
||||||
|
if (!BSesh.OnlineResult.Session.SessionSettings.bIsDedicated)
|
||||||
|
{
|
||||||
|
BSesh.OnlineResult.Session.SessionSettings.bUseLobbiesIfAvailable = true;
|
||||||
|
BSesh.OnlineResult.Session.SessionSettings.bUsesPresence = true;
|
||||||
|
}
|
||||||
|
|
||||||
Result.Add(BSesh);
|
Result.Add(BSesh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -16,7 +16,7 @@ UFindSessionsCallbackProxyAdvanced::UFindSessionsCallbackProxyAdvanced(const FOb
|
||||||
bIsOnSecondSearch = false;
|
bIsOnSecondSearch = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
UFindSessionsCallbackProxyAdvanced* UFindSessionsCallbackProxyAdvanced::FindSessionsAdvanced(UObject* WorldContextObject, class APlayerController* PlayerController, int MaxResults, bool bUseLAN, EBPServerPresenceSearchType ServerTypeToSearch, const TArray<FSessionsSearchSetting> &Filters, bool bEmptyServersOnly, bool bNonEmptyServersOnly, bool bSecureServersOnly, bool bSearchLobbies, int MinSlotsAvailable)
|
UFindSessionsCallbackProxyAdvanced* UFindSessionsCallbackProxyAdvanced::FindSessionsAdvanced(UObject* WorldContextObject, class APlayerController* PlayerController, int MaxResults, bool bUseLAN, EBPServerPresenceSearchType ServerTypeToSearch, const TArray<FSessionsSearchSetting> &Filters, bool bEmptyServersOnly, bool bNonEmptyServersOnly, bool bSecureServersOnly, /*bool bSearchLobbies,*/ int MinSlotsAvailable)
|
||||||
{
|
{
|
||||||
UFindSessionsCallbackProxyAdvanced* Proxy = NewObject<UFindSessionsCallbackProxyAdvanced>();
|
UFindSessionsCallbackProxyAdvanced* Proxy = NewObject<UFindSessionsCallbackProxyAdvanced>();
|
||||||
Proxy->PlayerControllerWeakPtr = PlayerController;
|
Proxy->PlayerControllerWeakPtr = PlayerController;
|
||||||
|
|
@ -28,7 +28,7 @@ UFindSessionsCallbackProxyAdvanced* UFindSessionsCallbackProxyAdvanced::FindSess
|
||||||
Proxy->bEmptyServersOnly = bEmptyServersOnly,
|
Proxy->bEmptyServersOnly = bEmptyServersOnly,
|
||||||
Proxy->bNonEmptyServersOnly = bNonEmptyServersOnly;
|
Proxy->bNonEmptyServersOnly = bNonEmptyServersOnly;
|
||||||
Proxy->bSecureServersOnly = bSecureServersOnly;
|
Proxy->bSecureServersOnly = bSecureServersOnly;
|
||||||
Proxy->bSearchLobbies = bSearchLobbies;
|
//Proxy->bSearchLobbies = bSearchLobbies;
|
||||||
Proxy->MinSlotsAvailable = MinSlotsAvailable;
|
Proxy->MinSlotsAvailable = MinSlotsAvailable;
|
||||||
return Proxy;
|
return Proxy;
|
||||||
}
|
}
|
||||||
|
|
@ -86,7 +86,6 @@ void UFindSessionsCallbackProxyAdvanced::Activate()
|
||||||
/** #define SEARCH_SWITCH_SELECTION_METHOD FName(TEXT("SWITCHSELECTIONMETHOD"))*/
|
/** #define SEARCH_SWITCH_SELECTION_METHOD FName(TEXT("SWITCHSELECTIONMETHOD"))*/
|
||||||
/** Whether to use lobbies vs sessions */
|
/** Whether to use lobbies vs sessions */
|
||||||
/** #define SEARCH_LOBBIES FName(TEXT("LOBBYSEARCH"))*/
|
/** #define SEARCH_LOBBIES FName(TEXT("LOBBYSEARCH"))*/
|
||||||
|
|
||||||
if (bEmptyServersOnly)
|
if (bEmptyServersOnly)
|
||||||
tem.Set(SEARCH_EMPTY_SERVERS_ONLY, true, EOnlineComparisonOp::Equals);
|
tem.Set(SEARCH_EMPTY_SERVERS_ONLY, true, EOnlineComparisonOp::Equals);
|
||||||
|
|
||||||
|
|
@ -114,9 +113,9 @@ void UFindSessionsCallbackProxyAdvanced::Activate()
|
||||||
|
|
||||||
case EBPServerPresenceSearchType::ClientServersOnly:
|
case EBPServerPresenceSearchType::ClientServersOnly:
|
||||||
{
|
{
|
||||||
tem.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals);
|
//tem.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals);
|
||||||
|
|
||||||
if (bSearchLobbies && !IOnlineSubsystem::DoesInstanceExist("STEAM"))
|
//if (bSearchLobbies)// && !IOnlineSubsystem::DoesInstanceExist("STEAM"))
|
||||||
tem.Set(SEARCH_LOBBIES, true, EOnlineComparisonOp::Equals);
|
tem.Set(SEARCH_LOBBIES, true, EOnlineComparisonOp::Equals);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -140,9 +139,9 @@ void UFindSessionsCallbackProxyAdvanced::Activate()
|
||||||
|
|
||||||
FOnlineSearchSettingsEx DedicatedOnly = tem;
|
FOnlineSearchSettingsEx DedicatedOnly = tem;
|
||||||
|
|
||||||
tem.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals);
|
//tem.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals);
|
||||||
|
|
||||||
if (bSearchLobbies && !IOnlineSubsystem::DoesInstanceExist("STEAM"))
|
//if (bSearchLobbies)// && !IOnlineSubsystem::DoesInstanceExist("STEAM"))
|
||||||
tem.Set(SEARCH_LOBBIES, true, EOnlineComparisonOp::Equals);
|
tem.Set(SEARCH_LOBBIES, true, EOnlineComparisonOp::Equals);
|
||||||
|
|
||||||
//DedicatedOnly.Set(SEARCH_DEDICATED_ONLY, true, EOnlineComparisonOp::Equals);
|
//DedicatedOnly.Set(SEARCH_DEDICATED_ONLY, true, EOnlineComparisonOp::Equals);
|
||||||
|
|
@ -225,6 +224,14 @@ void UFindSessionsCallbackProxyAdvanced::OnCompleted(bool bSuccess)
|
||||||
|
|
||||||
FBlueprintSessionResult BPResult;
|
FBlueprintSessionResult BPResult;
|
||||||
BPResult.OnlineResult = Result;
|
BPResult.OnlineResult = Result;
|
||||||
|
|
||||||
|
// Temp for 5.5, force the values if epic isn't setting them, lobbies should always have these true
|
||||||
|
if (ServerSearchType != EBPServerPresenceSearchType::DedicatedServersOnly )
|
||||||
|
{
|
||||||
|
BPResult.OnlineResult.Session.SessionSettings.bUseLobbiesIfAvailable = true;
|
||||||
|
BPResult.OnlineResult.Session.SessionSettings.bUsesPresence = true;
|
||||||
|
}
|
||||||
|
|
||||||
SessionSearchResults.AddUnique(BPResult);
|
SessionSearchResults.AddUnique(BPResult);
|
||||||
}
|
}
|
||||||
if (!bRunSecondSearch)
|
if (!bRunSecondSearch)
|
||||||
|
|
@ -12,7 +12,7 @@ UUpdateSessionCallbackProxyAdvanced::UUpdateSessionCallbackProxyAdvanced(const F
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
UUpdateSessionCallbackProxyAdvanced* UUpdateSessionCallbackProxyAdvanced::UpdateSession(UObject* WorldContextObject, const TArray<FSessionPropertyKeyPair> &ExtraSettings, int32 PublicConnections, int32 PrivateConnections, bool bUseLAN, bool bAllowInvites, bool bAllowJoinInProgress, bool bRefreshOnlineData, bool bIsDedicatedServer, bool bShouldAdvertise)
|
UUpdateSessionCallbackProxyAdvanced* UUpdateSessionCallbackProxyAdvanced::UpdateSession(UObject* WorldContextObject, const TArray<FSessionPropertyKeyPair> &ExtraSettings, int32 PublicConnections, int32 PrivateConnections, bool bUseLAN, bool bAllowInvites, bool bAllowJoinInProgress, bool bRefreshOnlineData, bool bIsDedicatedServer, bool bShouldAdvertise, bool bAllowJoinViaPresence, bool bAllowJoinViaPresenceFriendsOnly)
|
||||||
{
|
{
|
||||||
UUpdateSessionCallbackProxyAdvanced* Proxy = NewObject<UUpdateSessionCallbackProxyAdvanced>();
|
UUpdateSessionCallbackProxyAdvanced* Proxy = NewObject<UUpdateSessionCallbackProxyAdvanced>();
|
||||||
Proxy->NumPublicConnections = PublicConnections;
|
Proxy->NumPublicConnections = PublicConnections;
|
||||||
|
|
@ -25,6 +25,8 @@ UUpdateSessionCallbackProxyAdvanced* UUpdateSessionCallbackProxyAdvanced::Update
|
||||||
Proxy->bAllowJoinInProgress = bAllowJoinInProgress;
|
Proxy->bAllowJoinInProgress = bAllowJoinInProgress;
|
||||||
Proxy->bDedicatedServer = bIsDedicatedServer;
|
Proxy->bDedicatedServer = bIsDedicatedServer;
|
||||||
Proxy->bShouldAdvertise = bShouldAdvertise;
|
Proxy->bShouldAdvertise = bShouldAdvertise;
|
||||||
|
Proxy->bAllowJoinViaPresence = bAllowJoinViaPresence;
|
||||||
|
Proxy->bAllowJoinViaPresenceFriendsOnly = bAllowJoinViaPresenceFriendsOnly;
|
||||||
return Proxy;
|
return Proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,11 +67,14 @@ void UUpdateSessionCallbackProxyAdvanced::Activate()
|
||||||
Settings->bAllowJoinInProgress = bAllowJoinInProgress;
|
Settings->bAllowJoinInProgress = bAllowJoinInProgress;
|
||||||
Settings->bIsLANMatch = bUseLAN;
|
Settings->bIsLANMatch = bUseLAN;
|
||||||
//Settings->bUsesPresence = true;
|
//Settings->bUsesPresence = true;
|
||||||
//Settings->bAllowJoinViaPresence = true;
|
|
||||||
Settings->bAllowInvites = bAllowInvites;
|
Settings->bAllowInvites = bAllowInvites;
|
||||||
Settings->bAllowJoinInProgress = bAllowJoinInProgress;
|
Settings->bAllowJoinInProgress = bAllowJoinInProgress;
|
||||||
Settings->bIsDedicated = bDedicatedServer;
|
Settings->bIsDedicated = bDedicatedServer;
|
||||||
|
|
||||||
|
// Added in 5.6
|
||||||
|
Settings->bAllowJoinViaPresence = bAllowJoinViaPresence;
|
||||||
|
Settings->bAllowJoinViaPresenceFriendsOnly = bAllowJoinViaPresenceFriendsOnly;
|
||||||
|
|
||||||
FOnlineSessionSetting * fSetting = NULL;
|
FOnlineSessionSetting * fSetting = NULL;
|
||||||
FOnlineSessionSetting ExtraSetting;
|
FOnlineSessionSetting ExtraSetting;
|
||||||
for (int i = 0; i < ExtraSettings.Num(); i++)
|
for (int i = 0; i < ExtraSettings.Num(); i++)
|
||||||
|
|
@ -2,8 +2,8 @@
|
||||||
"FileVersion" : 3,
|
"FileVersion" : 3,
|
||||||
|
|
||||||
"FriendlyName" : "Advanced Steam Sessions",
|
"FriendlyName" : "Advanced Steam Sessions",
|
||||||
"Version" : 5.4,
|
"Version" : 5.7,
|
||||||
"VersionName": "5.4",
|
"VersionName": "5.7",
|
||||||
"Description" : "Adds new blueprint functions to handle more advanced session operations in Steam. REQUIRES ADVANCED SESSIONS",
|
"Description" : "Adds new blueprint functions to handle more advanced session operations in Steam. REQUIRES ADVANCED SESSIONS",
|
||||||
"Category" : "Advanced Sessions Plugin",
|
"Category" : "Advanced Sessions Plugin",
|
||||||
"CreatedBy" : "Joshua Statzer",
|
"CreatedBy" : "Joshua Statzer",
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
{
|
{
|
||||||
"Name": "AdvancedSteamSessions",
|
"Name": "AdvancedSteamSessions",
|
||||||
"Type": "RunTime",
|
"Type": "RunTime",
|
||||||
"LoadingPhase": "Default"
|
"LoadingPhase": "PostDefault"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Plugins": [
|
"Plugins": [
|
||||||
|
|
@ -5,6 +5,9 @@ public class AdvancedSteamSessions : ModuleRules
|
||||||
{
|
{
|
||||||
public AdvancedSteamSessions(ReadOnlyTargetRules Target) : base(Target)
|
public AdvancedSteamSessions(ReadOnlyTargetRules Target) : base(Target)
|
||||||
{
|
{
|
||||||
|
DefaultBuildSettings = BuildSettingsVersion.Latest;
|
||||||
|
IncludeOrderVersion = EngineIncludeOrderVersion.Latest;
|
||||||
|
|
||||||
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||||
//bEnforceIWYU = true;
|
//bEnforceIWYU = true;
|
||||||
|
|
||||||
|
|
@ -16,6 +19,7 @@ public class AdvancedSteamSessions : ModuleRules
|
||||||
if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Linux) || (Target.Platform == UnrealTargetPlatform.Mac))
|
if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Linux) || (Target.Platform == UnrealTargetPlatform.Mac))
|
||||||
{
|
{
|
||||||
PublicDependencyModuleNames.AddRange(new string[] { "SteamShared", "Steamworks", "OnlineSubsystemSteam" });
|
PublicDependencyModuleNames.AddRange(new string[] { "SteamShared", "Steamworks", "OnlineSubsystemSteam" });
|
||||||
|
AddEngineThirdPartyPrivateStaticDependencies(Target, "Steamworks");
|
||||||
//PublicIncludePaths.AddRange(new string[] { "../Plugins/Online/OnlineSubsystemSteam/Source/Private" });// This is dumb but it isn't very open
|
//PublicIncludePaths.AddRange(new string[] { "../Plugins/Online/OnlineSubsystemSteam/Source/Private" });// This is dumb but it isn't very open
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -42,7 +42,7 @@ MSVC_PRAGMA(warning(pop))
|
||||||
#endif // USING_CODE_ANALYSIS
|
#endif // USING_CODE_ANALYSIS
|
||||||
|
|
||||||
#include <steam/isteamapps.h>
|
#include <steam/isteamapps.h>
|
||||||
#include <steam/isteamapplist.h>
|
//#include <steam/isteamapplist.h>
|
||||||
//#include <OnlineSubsystemSteamTypes.h>
|
//#include <OnlineSubsystemSteamTypes.h>
|
||||||
#pragma pop_macro("ARRAY_COUNT")
|
#pragma pop_macro("ARRAY_COUNT")
|
||||||
|
|
||||||
|
|
@ -337,8 +337,8 @@ public:
|
||||||
static bool RequestSteamFriendInfo(const FBPUniqueNetId UniqueNetId, bool bRequireNameOnly = false);
|
static bool RequestSteamFriendInfo(const FBPUniqueNetId UniqueNetId, bool bRequireNameOnly = false);
|
||||||
|
|
||||||
// Opens the steam overlay to go to the specified user dialog
|
// Opens the steam overlay to go to the specified user dialog
|
||||||
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|SteamAPI")
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|SteamAPI", meta = (WorldContext = "WorldContextObject"))
|
||||||
static bool OpenSteamUserOverlay(const FBPUniqueNetId UniqueNetId, ESteamUserOverlayType DialogType);
|
static bool OpenSteamUserOverlay(UObject* WorldContextObject, const FBPUniqueNetId UniqueNetId, ESteamUserOverlayType DialogType);
|
||||||
|
|
||||||
// Returns if the steam overlay is currently active (this can return false during initial overlay hooking)
|
// Returns if the steam overlay is currently active (this can return false during initial overlay hooking)
|
||||||
UFUNCTION(BlueprintPure, Category = "Online|AdvancedFriends|SteamAPI")
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedFriends|SteamAPI")
|
||||||
|
|
@ -38,14 +38,27 @@ public:
|
||||||
void Initialize(USteamNotificationsSubsystem* MyParent)
|
void Initialize(USteamNotificationsSubsystem* MyParent)
|
||||||
{
|
{
|
||||||
ParentSubsystem = MyParent;
|
ParentSubsystem = MyParent;
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
OnExternalUITriggeredCallback.Register(this, &USteamNotificationsSubsystem::cSteamEventsStore::OnExternalUITriggered);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnInitialize(USteamNotificationsSubsystem* MyParent)
|
||||||
|
{
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
OnExternalUITriggeredCallback.Unregister();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
cSteamEventsStore() :
|
cSteamEventsStore()
|
||||||
OnExternalUITriggeredCallback(this, &cSteamEventsStore::OnExternalUITriggered)
|
{}
|
||||||
|
//:
|
||||||
|
/*OnExternalUITriggeredCallback(this, &cSteamEventsStore::OnExternalUITriggered)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}*/
|
||||||
#else
|
#else
|
||||||
//cSteamEventsStore()
|
//cSteamEventsStore()
|
||||||
//{
|
//{
|
||||||
|
|
@ -57,7 +70,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
STEAM_CALLBACK(cSteamEventsStore, OnExternalUITriggered, GameOverlayActivated_t, OnExternalUITriggeredCallback);
|
//STEAM_CALLBACK(cSteamEventsStore, OnExternalUITriggered, GameOverlayActivated_t, OnExternalUITriggeredCallback);
|
||||||
|
STEAM_CALLBACK_MANUAL(cSteamEventsStore, OnExternalUITriggered, GameOverlayActivated_t, OnExternalUITriggeredCallback);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -72,7 +86,7 @@ public:
|
||||||
/** Implement this for deinitialization of instances of the system */
|
/** Implement this for deinitialization of instances of the system */
|
||||||
virtual void Deinitialize() override
|
virtual void Deinitialize() override
|
||||||
{
|
{
|
||||||
|
MyEvents.UnInitialize(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
#include "AdvancedSteamFriendsLibrary.h"
|
#include "AdvancedSteamFriendsLibrary.h"
|
||||||
#include "OnlineSubSystemHeader.h"
|
#include "OnlineSubSystemHeader.h"
|
||||||
|
#include "OnlineSubsystemTypes.h"
|
||||||
|
#include "Engine/Texture.h"
|
||||||
|
#include "Engine/Texture2D.h"
|
||||||
|
#include "TextureResource.h"
|
||||||
|
#include "PixelFormat.h"
|
||||||
|
|
||||||
//General Log
|
//General Log
|
||||||
DEFINE_LOG_CATEGORY(AdvancedSteamFriendsLog);
|
DEFINE_LOG_CATEGORY(AdvancedSteamFriendsLog);
|
||||||
|
|
@ -233,7 +238,7 @@ bool UAdvancedSteamFriendsLibrary::RequestSteamFriendInfo(const FBPUniqueNetId U
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool UAdvancedSteamFriendsLibrary::OpenSteamUserOverlay(const FBPUniqueNetId UniqueNetId, ESteamUserOverlayType DialogType)
|
bool UAdvancedSteamFriendsLibrary::OpenSteamUserOverlay(UObject* WorldContextObject,const FBPUniqueNetId UniqueNetId, ESteamUserOverlayType DialogType)
|
||||||
{
|
{
|
||||||
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
if (!UniqueNetId.IsValid() || !UniqueNetId.UniqueNetId->IsValid() || UniqueNetId.UniqueNetId->GetType() != STEAM_SUBSYSTEM)
|
if (!UniqueNetId.IsValid() || !UniqueNetId.UniqueNetId->IsValid() || UniqueNetId.UniqueNetId->GetType() != STEAM_SUBSYSTEM)
|
||||||
|
|
@ -244,13 +249,24 @@ bool UAdvancedSteamFriendsLibrary::OpenSteamUserOverlay(const FBPUniqueNetId Uni
|
||||||
|
|
||||||
if (SteamAPI_Init())
|
if (SteamAPI_Init())
|
||||||
{
|
{
|
||||||
uint64 id = *((uint64*)UniqueNetId.UniqueNetId->GetBytes());
|
|
||||||
if (DialogType == ESteamUserOverlayType::invitetolobby)
|
if (DialogType == ESteamUserOverlayType::invitetolobby)
|
||||||
{
|
{
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(World);
|
||||||
|
if (SessionInterface.IsValid())
|
||||||
|
{
|
||||||
|
FNamedOnlineSession* CurrentSession = SessionInterface->GetNamedSession(NAME_GameSession);
|
||||||
|
|
||||||
|
if (CurrentSession && CurrentSession->SessionInfo->GetSessionId().IsValid())
|
||||||
|
{
|
||||||
|
uint64 id = *((uint64*)CurrentSession->SessionInfo->GetSessionId().GetBytes());
|
||||||
SteamFriends()->ActivateGameOverlayInviteDialog(id);
|
SteamFriends()->ActivateGameOverlayInviteDialog(id);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
uint64 id = *((uint64*)UniqueNetId.UniqueNetId->GetBytes());
|
||||||
FString DialogName = EnumToString("ESteamUserOverlayType", (uint8)DialogType);
|
FString DialogName = EnumToString("ESteamUserOverlayType", (uint8)DialogType);
|
||||||
SteamFriends()->ActivateGameOverlayToUser(TCHAR_TO_ANSI(*DialogName), id);
|
SteamFriends()->ActivateGameOverlayToUser(TCHAR_TO_ANSI(*DialogName), id);
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"FileVersion": 3,
|
"FileVersion": 3,
|
||||||
"Version": 5.5,
|
"Version": 5.7,
|
||||||
"VersionName": "5.5",
|
"VersionName": "5.7",
|
||||||
"FriendlyName": "OpenXRExpansionPlugin",
|
"FriendlyName": "OpenXRExpansionPlugin",
|
||||||
"Description": "An set of utility functions for OpenXR",
|
"Description": "An set of utility functions for OpenXR",
|
||||||
"Category": "Virtual Reality",
|
"Category": "Virtual Reality",
|
||||||
|
|
@ -163,34 +163,40 @@ void UOpenXRExpansionFunctionLibrary::GetXRMotionControllerType(FString& Trackin
|
||||||
|
|
||||||
bool UOpenXRExpansionFunctionLibrary::GetOpenXRHandPose(FBPOpenXRActionSkeletalData& HandPoseContainer, UOpenXRHandPoseComponent* HandPoseComponent, bool bGetMockUpPose)
|
bool UOpenXRExpansionFunctionLibrary::GetOpenXRHandPose(FBPOpenXRActionSkeletalData& HandPoseContainer, UOpenXRHandPoseComponent* HandPoseComponent, bool bGetMockUpPose)
|
||||||
{
|
{
|
||||||
FXRMotionControllerData MotionControllerData;
|
FXRHandTrackingState HandTrackingData;
|
||||||
|
FXRMotionControllerState MotionControllerData;
|
||||||
|
|
||||||
if (bGetMockUpPose)
|
if (bGetMockUpPose)
|
||||||
{
|
{
|
||||||
GetMockUpControllerData(MotionControllerData, HandPoseContainer);
|
// #TODO 5.7 TEST THIS
|
||||||
|
UHeadMountedDisplayFunctionLibrary::GetMotionControllerState((UObject*)HandPoseComponent, EXRSpaceType::UnrealWorldSpace, HandPoseContainer.TargetHand == EVRSkeletalHandIndex::EActionHandIndex_Left ? EControllerHand::Left : EControllerHand::Right, HandPoseContainer.PoseType, MotionControllerData);
|
||||||
|
GetMockUpControllerData(HandTrackingData,MotionControllerData, HandPoseContainer);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
UHeadMountedDisplayFunctionLibrary::GetMotionControllerData((UObject*)HandPoseComponent, HandPoseContainer.TargetHand == EVRSkeletalHandIndex::EActionHandIndex_Left ? EControllerHand::Left : EControllerHand::Right, MotionControllerData);
|
UHeadMountedDisplayFunctionLibrary::GetHandTrackingState((UObject*)HandPoseComponent, EXRSpaceType::UnrealWorldSpace, HandPoseContainer.TargetHand == EVRSkeletalHandIndex::EActionHandIndex_Left ? EControllerHand::Left : EControllerHand::Right, HandTrackingData);
|
||||||
|
|
||||||
if (MotionControllerData.bValid)
|
if (HandTrackingData.bValid)
|
||||||
{
|
{
|
||||||
HandPoseContainer.SkeletalTransforms.Empty(MotionControllerData.HandKeyPositions.Num());
|
HandPoseContainer.SkeletalTransforms.Empty(HandTrackingData.HandKeyLocations.Num());
|
||||||
FTransform ParentTrans = FTransform::Identity;
|
FTransform ParentTrans = FTransform::Identity;
|
||||||
|
|
||||||
if (MotionControllerData.DeviceVisualType == EXRVisualType::Controller)
|
|
||||||
|
// #TODO: 5.7 Preview!!
|
||||||
|
// Might need to restore all of this, have to test with vive
|
||||||
|
/*if (MotionControllerData.DeviceVisualType == EXRVisualType::Controller)
|
||||||
{
|
{
|
||||||
ParentTrans = FTransform(MotionControllerData.GripRotation, MotionControllerData.GripPosition, FVector(1.f));
|
ParentTrans = FTransform(MotionControllerData.GripRotation, MotionControllerData.GripPosition, FVector(1.f));
|
||||||
}
|
}
|
||||||
else // EXRVisualType::Hand visual type
|
else // EXRVisualType::Hand visual type*/
|
||||||
{
|
{
|
||||||
ParentTrans = FTransform(MotionControllerData.HandKeyRotations[(uint8)EHandKeypoint::Palm], MotionControllerData.HandKeyPositions[(uint8)EHandKeypoint::Palm], FVector(1.f));
|
ParentTrans = FTransform(HandTrackingData.HandKeyRotations[(uint8)EHandKeypoint::Palm], HandTrackingData.HandKeyLocations[(uint8)EHandKeypoint::Palm], FVector(1.f));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < MotionControllerData.HandKeyPositions.Num(); ++i)
|
for (int i = 0; i < HandTrackingData.HandKeyLocations.Num(); ++i)
|
||||||
{
|
{
|
||||||
// Convert to component space, we convert then to parent space later when applying it
|
// Convert to component space, we convert then to parent space later when applying it
|
||||||
HandPoseContainer.SkeletalTransforms.Add(FTransform(MotionControllerData.HandKeyRotations[i].GetNormalized(), MotionControllerData.HandKeyPositions[i], FVector(1.f)).GetRelativeTransform(ParentTrans));
|
HandPoseContainer.SkeletalTransforms.Add(FTransform(HandTrackingData.HandKeyRotations[i].GetNormalized(), HandTrackingData.HandKeyLocations[i], FVector(1.f)).GetRelativeTransform(ParentTrans));
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (bGetCurlValues)
|
//if (bGetCurlValues)
|
||||||
|
|
@ -233,31 +239,33 @@ bool UOpenXRExpansionFunctionLibrary::GetOpenXRFingerCurlValuesForHand(
|
||||||
float& RingCurl,
|
float& RingCurl,
|
||||||
float& PinkyCurl)
|
float& PinkyCurl)
|
||||||
{
|
{
|
||||||
FXRMotionControllerData MotionControllerData;
|
FXRHandTrackingState HandTrackingData;
|
||||||
UHeadMountedDisplayFunctionLibrary::GetMotionControllerData(WorldContextObject, TargetHand, MotionControllerData);
|
UHeadMountedDisplayFunctionLibrary::GetHandTrackingState(WorldContextObject, EXRSpaceType::UnrealWorldSpace, TargetHand, HandTrackingData);
|
||||||
|
|
||||||
// Fail if the count is too low
|
// Fail if the count is too low
|
||||||
if (MotionControllerData.HandKeyPositions.Num() < EHandKeypointCount)
|
if (HandTrackingData.HandKeyLocations.Num() < EHandKeypointCount)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
FTransform ParentTrans = FTransform::Identity;
|
FTransform ParentTrans = FTransform::Identity;
|
||||||
|
|
||||||
if (MotionControllerData.DeviceVisualType == EXRVisualType::Controller)
|
// #TODO: 5.7
|
||||||
|
// TEST THIS and restore if we need too
|
||||||
|
/*if (MotionControllerData.DeviceVisualType == EXRVisualType::Controller)
|
||||||
{
|
{
|
||||||
ParentTrans = FTransform(MotionControllerData.GripRotation, MotionControllerData.GripPosition, FVector(1.f));
|
ParentTrans = FTransform(MotionControllerData.GripRotation, MotionControllerData.GripPosition, FVector(1.f));
|
||||||
}
|
}
|
||||||
else // EXRVisualType::Hand visual type
|
else // EXRVisualType::Hand visual type*/
|
||||||
{
|
{
|
||||||
ParentTrans = FTransform(MotionControllerData.HandKeyRotations[(uint8)EHandKeypoint::Palm], MotionControllerData.HandKeyPositions[(uint8)EHandKeypoint::Palm], FVector(1.f));
|
ParentTrans = FTransform(HandTrackingData.HandKeyRotations[(uint8)EHandKeypoint::Palm], HandTrackingData.HandKeyLocations[(uint8)EHandKeypoint::Palm], FVector(1.f));
|
||||||
}
|
}
|
||||||
|
|
||||||
TArray<FTransform> TransformArray;
|
TArray<FTransform> TransformArray;
|
||||||
TransformArray.AddUninitialized(MotionControllerData.HandKeyPositions.Num());
|
TransformArray.AddUninitialized(HandTrackingData.HandKeyLocations.Num());
|
||||||
|
|
||||||
for (int i = 0; i < MotionControllerData.HandKeyPositions.Num(); ++i)
|
for (int i = 0; i < HandTrackingData.HandKeyLocations.Num(); ++i)
|
||||||
{
|
{
|
||||||
// Convert to component space, we convert then to parent space later when applying it
|
// Convert to component space, we convert then to parent space later when applying it
|
||||||
TransformArray[i] = FTransform(MotionControllerData.HandKeyRotations[i].GetNormalized(), MotionControllerData.HandKeyPositions[i], FVector(1.f)).GetRelativeTransform(ParentTrans);
|
TransformArray[i] = FTransform(HandTrackingData.HandKeyRotations[i].GetNormalized(), HandTrackingData.HandKeyLocations[i], FVector(1.f)).GetRelativeTransform(ParentTrans);
|
||||||
}
|
}
|
||||||
|
|
||||||
ThumbCurl = GetCurlValueForBoneRoot(TransformArray, EHandKeypoint::ThumbMetacarpal);
|
ThumbCurl = GetCurlValueForBoneRoot(TransformArray, EHandKeypoint::ThumbMetacarpal);
|
||||||
|
|
@ -436,7 +444,7 @@ void UOpenXRExpansionFunctionLibrary::ConvertHandTransformsSpaceAndBack(TArray<F
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UOpenXRExpansionFunctionLibrary::GetMockUpControllerData(FXRMotionControllerData& MotionControllerData, FBPOpenXRActionSkeletalData& SkeletalMappingData, bool bOpenHand)
|
void UOpenXRExpansionFunctionLibrary::GetMockUpControllerData(FXRHandTrackingState& HandTrackingData, FXRMotionControllerState& MotionControllerData, FBPOpenXRActionSkeletalData& SkeletalMappingData, bool bOpenHand)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -499,7 +507,7 @@ void UOpenXRExpansionFunctionLibrary::GetMockUpControllerData(FXRMotionControlle
|
||||||
FQuat(0.116890728f,-0.981477261f,0.138804480f,-0.061412390f)
|
FQuat(0.116890728f,-0.981477261f,0.138804480f,-0.061412390f)
|
||||||
};
|
};
|
||||||
|
|
||||||
MotionControllerData.HandKeyRotations = /*SkeletalMappingData.TargetHand != EVRSkeletalHandIndex::EActionHandIndex_Left ? HandRotationsOpen :*/ HandRotationsClosed;
|
HandTrackingData.HandKeyRotations = /*SkeletalMappingData.TargetHand != EVRSkeletalHandIndex::EActionHandIndex_Left ? HandRotationsOpen :*/ HandRotationsClosed;
|
||||||
|
|
||||||
TArray<FVector> HandPositionsClosed = {
|
TArray<FVector> HandPositionsClosed = {
|
||||||
// Closed palm - Left
|
// Closed palm - Left
|
||||||
|
|
@ -561,9 +569,9 @@ void UOpenXRExpansionFunctionLibrary::GetMockUpControllerData(FXRMotionControlle
|
||||||
FVector(-1019.778f,-479.842f,203.819f)
|
FVector(-1019.778f,-479.842f,203.819f)
|
||||||
};
|
};
|
||||||
|
|
||||||
MotionControllerData.HandKeyPositions = /*SkeletalMappingData.TargetHand != EVRSkeletalHandIndex::EActionHandIndex_Left ? HandPositionsOpen : */HandPositionsClosed;
|
HandTrackingData.HandKeyLocations = /*SkeletalMappingData.TargetHand != EVRSkeletalHandIndex::EActionHandIndex_Left ? HandPositionsOpen : */HandPositionsClosed;
|
||||||
|
|
||||||
if (SkeletalMappingData.TargetHand != EVRSkeletalHandIndex::EActionHandIndex_Left)
|
/*if (SkeletalMappingData.TargetHand != EVRSkeletalHandIndex::EActionHandIndex_Left)
|
||||||
{
|
{
|
||||||
MotionControllerData.GripPosition = FVector(-1018.305f, -478.019f, 209.872f);
|
MotionControllerData.GripPosition = FVector(-1018.305f, -478.019f, 209.872f);
|
||||||
MotionControllerData.GripRotation = FQuat(-0.116352126f, 0.039430488f, -0.757644236f, 0.641001403f);
|
MotionControllerData.GripRotation = FQuat(-0.116352126f, 0.039430488f, -0.757644236f, 0.641001403f);
|
||||||
|
|
@ -572,15 +580,15 @@ void UOpenXRExpansionFunctionLibrary::GetMockUpControllerData(FXRMotionControlle
|
||||||
{
|
{
|
||||||
MotionControllerData.GripPosition = FVector(-1202.619f, -521.077f, 283.076f);
|
MotionControllerData.GripPosition = FVector(-1202.619f, -521.077f, 283.076f);
|
||||||
MotionControllerData.GripRotation = FQuat(0.040843058f, 0.116659224f, 0.980030060f, -0.155767411f);
|
MotionControllerData.GripRotation = FQuat(0.040843058f, 0.116659224f, 0.980030060f, -0.155767411f);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
MotionControllerData.DeviceName = TEXT("OpenXR");
|
HandTrackingData.DeviceName = TEXT("OpenXR");
|
||||||
|
|
||||||
SkeletalMappingData.SkeletalTransforms.Empty(SkeletalMappingData.SkeletalTransforms.Num());
|
SkeletalMappingData.SkeletalTransforms.Empty(SkeletalMappingData.SkeletalTransforms.Num());
|
||||||
FTransform ParentTrans = FTransform(MotionControllerData.GripRotation, MotionControllerData.GripPosition, FVector(1.f));
|
FTransform ParentTrans = FTransform(MotionControllerData.GripUnrealSpaceRotation, MotionControllerData.GripUnrealSpaceLocation, FVector(1.f));
|
||||||
for (int i = 0; i < MotionControllerData.HandKeyPositions.Num(); i++)
|
for (int i = 0; i < HandTrackingData.HandKeyLocations.Num(); i++)
|
||||||
{
|
{
|
||||||
SkeletalMappingData.SkeletalTransforms.Add(FTransform(MotionControllerData.HandKeyRotations[i], MotionControllerData.HandKeyPositions[i], FVector(1.f)).GetRelativeTransform(ParentTrans));
|
SkeletalMappingData.SkeletalTransforms.Add(FTransform(HandTrackingData.HandKeyRotations[i], HandTrackingData.HandKeyLocations[i], FVector(1.f)).GetRelativeTransform(ParentTrans));
|
||||||
}
|
}
|
||||||
|
|
||||||
SkeletalMappingData.bHasValidData = (SkeletalMappingData.SkeletalTransforms.Num() == EHandKeypointCount);
|
SkeletalMappingData.bHasValidData = (SkeletalMappingData.SkeletalTransforms.Num() == EHandKeypointCount);
|
||||||
|
|
@ -0,0 +1,340 @@
|
||||||
|
#include "Serializers/FBPXRSkeletalRepContainerNetSerializer.h"
|
||||||
|
#include "Iris/Serialization/NetSerializerDelegates.h"
|
||||||
|
#include "Iris/Serialization/NetSerializers.h"
|
||||||
|
#include "Iris/Serialization/PackedVectorNetSerializers.h"
|
||||||
|
#include "Iris/ReplicationState/PropertyNetSerializerInfoRegistry.h"
|
||||||
|
#include "Iris/ReplicationState/ReplicationStateDescriptorBuilder.h"
|
||||||
|
|
||||||
|
#include "OpenXRHandPoseComponent.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace UE::Net
|
||||||
|
{
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Iris serializer for FBPXRSkeletalRepContainer
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
struct FBPXRSkeletalRepContainerNetSerializer
|
||||||
|
{
|
||||||
|
inline static const FVectorNetQuantize100NetSerializerConfig Quantize100SerializerConfig;
|
||||||
|
|
||||||
|
inline static const FNetSerializerConfig* VectorNetQuantizeNetSerializerConfig = &Quantize100SerializerConfig;
|
||||||
|
inline static const FNetSerializer* VectorNetQuantizeNetSerializer;
|
||||||
|
|
||||||
|
class FNetSerializerRegistryDelegates final : private UE::Net::FNetSerializerRegistryDelegates
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~FNetSerializerRegistryDelegates();
|
||||||
|
|
||||||
|
void InitNetSerializer()
|
||||||
|
{
|
||||||
|
FBPXRSkeletalRepContainerNetSerializer::VectorNetQuantizeNetSerializer = &UE_NET_GET_SERIALIZER(FVectorNetQuantize100NetSerializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void OnPreFreezeNetSerializerRegistry() override;
|
||||||
|
//virtual void OnPostFreezeNetSerializerRegistry() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline static FBPXRSkeletalRepContainerNetSerializer::FNetSerializerRegistryDelegates NetSerializerRegistryDelegates;
|
||||||
|
|
||||||
|
|
||||||
|
/** Version is required. */
|
||||||
|
static constexpr uint32 Version = 0;
|
||||||
|
|
||||||
|
struct alignas(8) FSkeletalTransformQuantizedData
|
||||||
|
{
|
||||||
|
uint64 Position[4]; // We don't need to store double for tracked device positions, but their forwarded serializer uses it
|
||||||
|
uint16 Rotation[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct alignas(8) FBPXRSkeletalRepContainerQuantizedData
|
||||||
|
{
|
||||||
|
uint8 TargetHand;
|
||||||
|
uint8 bAllowDeformingMesh;
|
||||||
|
uint8 bEnableUE4HandRepSavings;
|
||||||
|
|
||||||
|
uint16 ElementCount;
|
||||||
|
FSkeletalTransformQuantizedData SkeletalTransforms[EHandKeypointCount];
|
||||||
|
// List of array data, we know the max elements so we can statically set it to that
|
||||||
|
// Technically should be -6 since we dont use some but im going to future proof it a bit here
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef FBPXRSkeletalRepContainer SourceType;
|
||||||
|
typedef FBPXRSkeletalRepContainerQuantizedData QuantizedType;
|
||||||
|
typedef FBPXRSkeletalRepContainerNetSerializerConfig ConfigType;
|
||||||
|
inline static const ConfigType DefaultConfig;
|
||||||
|
|
||||||
|
/** Set to false when a same value delta compression method is undesirable, for example when the serializer only writes a single bit for the state. */
|
||||||
|
static constexpr bool bUseDefaultDelta = true;
|
||||||
|
|
||||||
|
// Not using delta as this struct is sent on a timer and not changed incrementally
|
||||||
|
|
||||||
|
|
||||||
|
static constexpr uint32 ElementSizeBytes = sizeof(FSkeletalTransformQuantizedData);
|
||||||
|
|
||||||
|
// Called to create a "quantized snapshot" of the struct
|
||||||
|
static void Quantize(FNetSerializationContext& Context, const FNetQuantizeArgs& Args)
|
||||||
|
{
|
||||||
|
// Actually do the real quantization step here next instead of just in serialize, will save on memory overall
|
||||||
|
const SourceType& Source = *reinterpret_cast<const SourceType*>(Args.Source);
|
||||||
|
QuantizedType& Target = *reinterpret_cast<QuantizedType*>(Args.Target);
|
||||||
|
|
||||||
|
Target.TargetHand = (uint8)Source.TargetHand;
|
||||||
|
Target.bAllowDeformingMesh = Source.bAllowDeformingMesh ? 1 : 0;
|
||||||
|
Target.bEnableUE4HandRepSavings = Source.bEnableUE4HandRepSavings ? 1 : 0;
|
||||||
|
|
||||||
|
// Free data if non null
|
||||||
|
Target.ElementCount = 0;
|
||||||
|
|
||||||
|
const uint32 Num = Source.SkeletalTransforms.Num();
|
||||||
|
Target.ElementCount = static_cast<uint16>(Num);
|
||||||
|
|
||||||
|
if (Num > 0)
|
||||||
|
{
|
||||||
|
FRotator TargetRot;
|
||||||
|
FVector TargetLoc;
|
||||||
|
for (uint16 i = 0; i < Num; ++i)
|
||||||
|
{
|
||||||
|
TargetRot = Source.SkeletalTransforms[i].Rotator();
|
||||||
|
TargetLoc = Source.SkeletalTransforms[i].GetLocation();
|
||||||
|
|
||||||
|
Target.SkeletalTransforms[i].Rotation[0] = FRotator::CompressAxisToShort(TargetRot.Pitch);
|
||||||
|
Target.SkeletalTransforms[i].Rotation[1] = FRotator::CompressAxisToShort(TargetRot.Yaw);
|
||||||
|
Target.SkeletalTransforms[i].Rotation[2] = FRotator::CompressAxisToShort(TargetRot.Roll);
|
||||||
|
|
||||||
|
const FNetSerializer* Serializer = VectorNetQuantizeNetSerializer;
|
||||||
|
const FNetSerializerConfig* SerializerConfig = VectorNetQuantizeNetSerializerConfig;
|
||||||
|
|
||||||
|
FNetQuantizeArgs MemberArgs = Args;
|
||||||
|
MemberArgs.NetSerializerConfig = NetSerializerConfigParam(SerializerConfig);
|
||||||
|
MemberArgs.Source = NetSerializerValuePointer(&TargetLoc);
|
||||||
|
MemberArgs.Target = NetSerializerValuePointer(&Target.SkeletalTransforms[i].Position[0]);
|
||||||
|
Serializer->Quantize(Context, MemberArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called to apply the quantized snapshot back to gameplay memory
|
||||||
|
static void Dequantize(FNetSerializationContext& Context, const FNetDequantizeArgs& Args)
|
||||||
|
{
|
||||||
|
const QuantizedType& Source = *reinterpret_cast<const QuantizedType*>(Args.Source);
|
||||||
|
SourceType& Target = *reinterpret_cast<SourceType*>(Args.Target);
|
||||||
|
|
||||||
|
Target.TargetHand = (EVRSkeletalHandIndex)Source.TargetHand;
|
||||||
|
Target.bAllowDeformingMesh = Source.bAllowDeformingMesh != 0;
|
||||||
|
Target.bEnableUE4HandRepSavings = Source.bEnableUE4HandRepSavings != 0;
|
||||||
|
|
||||||
|
const uint16 Count = Source.ElementCount;
|
||||||
|
Target.SkeletalTransforms.Reset();
|
||||||
|
if (Count > 0)
|
||||||
|
{
|
||||||
|
Target.SkeletalTransforms.AddUninitialized(Count);
|
||||||
|
|
||||||
|
const FSkeletalTransformQuantizedData* Data = Source.SkeletalTransforms;
|
||||||
|
FRotator TargetRot;
|
||||||
|
FVector TargetLoc;
|
||||||
|
for (int i = 0; i < Count; ++i)
|
||||||
|
{
|
||||||
|
TargetRot.Pitch = FRotator::DecompressAxisFromShort(Data[i].Rotation[0]);
|
||||||
|
TargetRot.Yaw = FRotator::DecompressAxisFromShort(Data[i].Rotation[1]);
|
||||||
|
TargetRot.Roll = FRotator::DecompressAxisFromShort(Data[i].Rotation[2]);
|
||||||
|
TargetRot.Normalize();
|
||||||
|
|
||||||
|
const FNetSerializer* Serializer = VectorNetQuantizeNetSerializer;
|
||||||
|
const FNetSerializerConfig* SerializerConfig = VectorNetQuantizeNetSerializerConfig;
|
||||||
|
|
||||||
|
FNetDequantizeArgs MemberArgs = Args;
|
||||||
|
MemberArgs.NetSerializerConfig = NetSerializerConfigParam(SerializerConfig);
|
||||||
|
MemberArgs.Source = NetSerializerValuePointer(&TargetLoc);
|
||||||
|
MemberArgs.Target = NetSerializerValuePointer(&Data[i].Position[0]);
|
||||||
|
Serializer->Dequantize(Context, MemberArgs);
|
||||||
|
|
||||||
|
Target.SkeletalTransforms[i].SetComponents(TargetRot.Quaternion(), TargetLoc, FVector(1.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serialize into bitstream
|
||||||
|
static void Serialize(FNetSerializationContext& Context, const FNetSerializeArgs& Args)
|
||||||
|
{
|
||||||
|
const QuantizedType& Source = *reinterpret_cast<const QuantizedType*>(Args.Source);
|
||||||
|
FNetBitStreamWriter* Writer = Context.GetBitStreamWriter();
|
||||||
|
|
||||||
|
// write header bytes (small fields) — do as bytes for compactness
|
||||||
|
Writer->WriteBits(Source.TargetHand, 8);
|
||||||
|
Writer->WriteBits(Source.bAllowDeformingMesh, 1);
|
||||||
|
Writer->WriteBits(Source.bEnableUE4HandRepSavings, 1);
|
||||||
|
|
||||||
|
int32 BoneCountAdjustment = 6 + (Source.bEnableUE4HandRepSavings != 0 ? 4 : 0);
|
||||||
|
uint8 TransformCount = EHandKeypointCount - BoneCountAdjustment;
|
||||||
|
|
||||||
|
bool bHasValidData = Source.ElementCount >= TransformCount;
|
||||||
|
|
||||||
|
Writer->WriteBits(bHasValidData, 1);
|
||||||
|
|
||||||
|
if (bHasValidData)
|
||||||
|
{
|
||||||
|
// write element count (16 bits)
|
||||||
|
uint32 ElemCount = Source.ElementCount;
|
||||||
|
|
||||||
|
if (ElemCount < 1)
|
||||||
|
{
|
||||||
|
// Write nothing
|
||||||
|
ElemCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Writer->WriteBits(ElemCount, 16);
|
||||||
|
|
||||||
|
const FSkeletalTransformQuantizedData* Data = Source.SkeletalTransforms;
|
||||||
|
for (uint16 i = 0; i < ElemCount; ++i)
|
||||||
|
{
|
||||||
|
if (Source.bAllowDeformingMesh)
|
||||||
|
{
|
||||||
|
const FNetSerializer* Serializer = VectorNetQuantizeNetSerializer;
|
||||||
|
const FNetSerializerConfig* SerializerConfig = VectorNetQuantizeNetSerializerConfig;
|
||||||
|
|
||||||
|
FNetSerializeArgs MemberArgs = Args;
|
||||||
|
MemberArgs.NetSerializerConfig = NetSerializerConfigParam(SerializerConfig);
|
||||||
|
MemberArgs.Source = NetSerializerValuePointer(&Data[i].Position[0]);
|
||||||
|
Serializer->Serialize(Context, MemberArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Writer->WriteBits(Data[i].Rotation[0], 16);
|
||||||
|
Writer->WriteBits(Data[i].Rotation[1], 16);
|
||||||
|
Writer->WriteBits(Data[i].Rotation[2], 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deserialize from bitstream
|
||||||
|
static void Deserialize(FNetSerializationContext& Context, const FNetDeserializeArgs& Args)
|
||||||
|
{
|
||||||
|
QuantizedType& Target = *reinterpret_cast<QuantizedType*>(Args.Target);
|
||||||
|
FNetBitStreamReader* Reader = Context.GetBitStreamReader();
|
||||||
|
|
||||||
|
// write header bytes (small fields) — do as bytes for compactness
|
||||||
|
|
||||||
|
Target.TargetHand = Reader->ReadBits(8);
|
||||||
|
Target.bAllowDeformingMesh = Reader->ReadBits(1);
|
||||||
|
Target.bEnableUE4HandRepSavings = Reader->ReadBits(1);
|
||||||
|
|
||||||
|
int32 BoneCountAdjustment = 6 + (Target.bEnableUE4HandRepSavings != 0 ? 4 : 0);
|
||||||
|
uint8 TransformCount = EHandKeypointCount - BoneCountAdjustment;
|
||||||
|
|
||||||
|
bool bHasValidData = Reader->ReadBits(1) != 0;
|
||||||
|
|
||||||
|
if (bHasValidData)
|
||||||
|
{
|
||||||
|
// write element count (16 bits)
|
||||||
|
uint32 ElemCount = Reader->ReadBits(16);
|
||||||
|
|
||||||
|
Target.ElementCount = static_cast<uint16>(ElemCount);
|
||||||
|
|
||||||
|
if (ElemCount > 0)
|
||||||
|
{
|
||||||
|
FSkeletalTransformQuantizedData* Data = Target.SkeletalTransforms;
|
||||||
|
for (uint16 i = 0; i < ElemCount; ++i)
|
||||||
|
{
|
||||||
|
if (Target.bAllowDeformingMesh)
|
||||||
|
{
|
||||||
|
const FNetSerializer* Serializer = VectorNetQuantizeNetSerializer;
|
||||||
|
const FNetSerializerConfig* SerializerConfig = VectorNetQuantizeNetSerializerConfig;
|
||||||
|
|
||||||
|
FNetDeserializeArgs MemberArgs = Args;
|
||||||
|
MemberArgs.NetSerializerConfig = NetSerializerConfigParam(SerializerConfig);
|
||||||
|
MemberArgs.Target = NetSerializerValuePointer(&Data[i].Position[0]);
|
||||||
|
Serializer->Deserialize(Context, MemberArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Data[i].Rotation[0] = Reader->ReadBits(16);
|
||||||
|
Data[i].Rotation[1] = Reader->ReadBits(16);
|
||||||
|
Data[i].Rotation[2] = Reader->ReadBits(16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Compare two instances to see if they differ
|
||||||
|
static bool IsEqual(FNetSerializationContext& Context, const FNetIsEqualArgs& Args)
|
||||||
|
{
|
||||||
|
if (Args.bStateIsQuantized)
|
||||||
|
{
|
||||||
|
const QuantizedType& QuantizedValue0 = *reinterpret_cast<const QuantizedType*>(Args.Source0);
|
||||||
|
const QuantizedType& QuantizedValue1 = *reinterpret_cast<const QuantizedType*>(Args.Source1);
|
||||||
|
return FPlatformMemory::Memcmp(&QuantizedValue0, &QuantizedValue1, sizeof(QuantizedType)) == 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const SourceType& L = *reinterpret_cast<const SourceType*>(Args.Source0);
|
||||||
|
const SourceType& R = *reinterpret_cast<const SourceType*>(Args.Source1);
|
||||||
|
|
||||||
|
|
||||||
|
if (L.bAllowDeformingMesh != R.bAllowDeformingMesh) return false;
|
||||||
|
if (L.bEnableUE4HandRepSavings != R.bEnableUE4HandRepSavings) return false;
|
||||||
|
if (L.SkeletalTransforms.Num() != R.SkeletalTransforms.Num()) return false;
|
||||||
|
|
||||||
|
// Using L num is valid as we already checked if they are the same count
|
||||||
|
return FPlatformMemory::Memcmp(L.SkeletalTransforms.GetData(), R.SkeletalTransforms.GetData(), sizeof(FTransform) * L.SkeletalTransforms.Num()) == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Apply(FNetSerializationContext& Context, const FNetApplyArgs& Args)
|
||||||
|
{
|
||||||
|
const SourceType& Source = *reinterpret_cast<const SourceType*>(Args.Source);
|
||||||
|
SourceType& Target = *reinterpret_cast<SourceType*>(Args.Target);
|
||||||
|
|
||||||
|
Target.bAllowDeformingMesh = Source.bAllowDeformingMesh;
|
||||||
|
Target.bEnableUE4HandRepSavings = Source.bEnableUE4HandRepSavings;
|
||||||
|
Target.TargetHand = Source.TargetHand;
|
||||||
|
|
||||||
|
// Copys it over with new allocations
|
||||||
|
Target.SkeletalTransforms = Source.SkeletalTransforms;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CloneDynamicState(FNetSerializationContext& Context, const FNetCloneDynamicStateArgs& Args)
|
||||||
|
{
|
||||||
|
const QuantizedType& Source = *reinterpret_cast<QuantizedType*>(Args.Source);
|
||||||
|
QuantizedType& Target = *reinterpret_cast<QuantizedType*>(Args.Target);
|
||||||
|
|
||||||
|
// copy small fields
|
||||||
|
Target.TargetHand = Source.TargetHand;
|
||||||
|
Target.bAllowDeformingMesh = Source.bAllowDeformingMesh;
|
||||||
|
Target.bEnableUE4HandRepSavings = Source.bEnableUE4HandRepSavings;
|
||||||
|
|
||||||
|
// copy elements
|
||||||
|
Target.ElementCount = Source.ElementCount;
|
||||||
|
|
||||||
|
const uint32 Count = Target.ElementCount;
|
||||||
|
if (Count > 0)
|
||||||
|
{
|
||||||
|
const SIZE_T Bytes = SIZE_T(Count) * ElementSizeBytes;
|
||||||
|
FMemory::Memcpy(Target.SkeletalTransforms, Source.SkeletalTransforms, Bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FreeDynamicState(FNetSerializationContext& Context, const FNetFreeDynamicStateArgs& Args)
|
||||||
|
{
|
||||||
|
QuantizedType& Target = *reinterpret_cast<QuantizedType*>(Args.Source);
|
||||||
|
Target.ElementCount = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const FName PropertyNetSerializerRegistry_NAME_BPXRSkeletalRepContainer("BPXRSkeletalRepContainer");
|
||||||
|
UE_NET_IMPLEMENT_NAMED_STRUCT_NETSERIALIZER_INFO(PropertyNetSerializerRegistry_NAME_BPXRSkeletalRepContainer, FBPXRSkeletalRepContainerNetSerializer);
|
||||||
|
|
||||||
|
FBPXRSkeletalRepContainerNetSerializer::FNetSerializerRegistryDelegates::~FNetSerializerRegistryDelegates()
|
||||||
|
{
|
||||||
|
UE_NET_UNREGISTER_NETSERIALIZER_INFO(PropertyNetSerializerRegistry_NAME_BPXRSkeletalRepContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FBPXRSkeletalRepContainerNetSerializer::FNetSerializerRegistryDelegates::OnPreFreezeNetSerializerRegistry()
|
||||||
|
{
|
||||||
|
InitNetSerializer();
|
||||||
|
UE_NET_REGISTER_NETSERIALIZER_INFO(PropertyNetSerializerRegistry_NAME_BPXRSkeletalRepContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
UE_NET_IMPLEMENT_SERIALIZER(FBPXRSkeletalRepContainerNetSerializer);
|
||||||
|
}
|
||||||
|
|
@ -93,7 +93,7 @@ public:
|
||||||
static void ConvertHandTransformsSpaceAndBack(TArray<FTransform>& OutTransforms, const TArray<FTransform>& WorldTransforms);
|
static void ConvertHandTransformsSpaceAndBack(TArray<FTransform>& OutTransforms, const TArray<FTransform>& WorldTransforms);
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|OpenXR", meta = (bIgnoreSelf = "true"))
|
UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|OpenXR", meta = (bIgnoreSelf = "true"))
|
||||||
static void GetMockUpControllerData(FXRMotionControllerData& MotionControllerData, FBPOpenXRActionSkeletalData& SkeletalMappingData, bool bOpenHand = false);
|
static void GetMockUpControllerData(FXRHandTrackingState& HandTrackingData,FXRMotionControllerState& MotionControllerData, FBPOpenXRActionSkeletalData& SkeletalMappingData, bool bOpenHand = false);
|
||||||
|
|
||||||
// Get a list of all currently tracked devices and their types, index in the array is their device index
|
// Get a list of all currently tracked devices and their types, index in the array is their device index
|
||||||
// Returns failed if the openXR query failed (no interaction profile yet or openXR is not running)
|
// Returns failed if the openXR query failed (no interaction profile yet or openXR is not running)
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "UObject/ObjectMacros.h"
|
#include "UObject/ObjectMacros.h"
|
||||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||||
|
#include "HeadMountedDisplayTypes.h"
|
||||||
#include "Animation/BoneReference.h"
|
#include "Animation/BoneReference.h"
|
||||||
#include "UObject/Object.h"
|
#include "UObject/Object.h"
|
||||||
#include "Engine/EngineTypes.h"
|
#include "Engine/EngineTypes.h"
|
||||||
|
|
@ -97,6 +98,10 @@ public:
|
||||||
UPROPERTY(EditAnywhere, NotReplicated, BlueprintReadWrite, Category = Default)
|
UPROPERTY(EditAnywhere, NotReplicated, BlueprintReadWrite, Category = Default)
|
||||||
EVRSkeletalHandIndex TargetHand;
|
EVRSkeletalHandIndex TargetHand;
|
||||||
|
|
||||||
|
// Used to select the type of pose to retrieve from OpenXR, default is grip but you will want to use Palm when using the palm source for motion controller
|
||||||
|
UPROPERTY(EditAnywhere, NotReplicated, BlueprintReadWrite, Category = Default)
|
||||||
|
EXRControllerPoseType PoseType;
|
||||||
|
|
||||||
// A world scale override that will replace the engines current value and force into the tracked data if non zero
|
// A world scale override that will replace the engines current value and force into the tracked data if non zero
|
||||||
UPROPERTY(EditAnywhere, NotReplicated, BlueprintReadWrite, Category = Default)
|
UPROPERTY(EditAnywhere, NotReplicated, BlueprintReadWrite, Category = Default)
|
||||||
float WorldScaleOverride;
|
float WorldScaleOverride;
|
||||||
|
|
@ -144,6 +149,7 @@ public:
|
||||||
bMirrorLeftRight = false;
|
bMirrorLeftRight = false;
|
||||||
bEnableUE4HandRepSavings = false;
|
bEnableUE4HandRepSavings = false;
|
||||||
TargetHand = EVRSkeletalHandIndex::EActionHandIndex_Right;
|
TargetHand = EVRSkeletalHandIndex::EActionHandIndex_Right;
|
||||||
|
PoseType = EXRControllerPoseType::Grip;
|
||||||
bHasValidData = false;
|
bHasValidData = false;
|
||||||
LastHandGestureIndex = INDEX_NONE;
|
LastHandGestureIndex = INDEX_NONE;
|
||||||
LastHandGesture = NAME_None;
|
LastHandGesture = NAME_None;
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Iris/Serialization/NetSerializer.h"
|
||||||
|
#include "FBPXRSkeletalRepContainerNetSerializer.generated.h"
|
||||||
|
|
||||||
|
USTRUCT()
|
||||||
|
struct FBPXRSkeletalRepContainerNetSerializerConfig : public FNetSerializerConfig
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace UE::Net
|
||||||
|
{
|
||||||
|
UE_NET_DECLARE_SERIALIZER(FBPXRSkeletalRepContainerNetSerializer, OPENXREXPANSIONPLUGIN_API);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 968fe10c9f08859c64ea88768d5216140fc340d9
|
Subproject commit 57c25ee516342f3a4140ca52eb9025580a4f2fd8
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit d6fbc18c862cc9d1e9c8418a16273a8562078403
|
Subproject commit 5fe193da6208fbd9626559a66e332c5642496ab3
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
* text=auto
|
|
||||||
*.bat eol=crlf
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
|
|
||||||
.hg/
|
|
||||||
binaries/
|
|
||||||
deriveddatacache/
|
|
||||||
.vs/
|
|
||||||
build/
|
|
||||||
intermediate/
|
|
||||||
PACKPLUGIN/
|
|
||||||
saved/
|
|
||||||
*.orig
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
Copyright Joshua Statzer
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
UE Forums Thread
|
|
||||||
https://forums.unrealengine.com/development-discussion/vr-ar-development/89050-vr-openvr-expansion-plugin
|
|
||||||
|
|
||||||
Example Template Project
|
|
||||||
https://github.com/mordentral/VRExpPluginExample
|
|
||||||
|
|
||||||
Website:
|
|
||||||
www.vreue4.com
|
|
||||||
|
|
||||||
***
|
|
||||||
|
|
||||||
### Use Of This Plugin ###
|
|
||||||
|
|
||||||
This Plugin is intended to add additional functionality to Open/SteamVR/(All VR now) in UE4.
|
|
||||||
|
|
||||||
### Plugin Website ###
|
|
||||||
[VREUE4.com](https://vreue4.com)
|
|
||||||
|
|
||||||
### How do I install it? ###
|
|
||||||
|
|
||||||
https://vreue4.com/documentation?section=installation
|
|
||||||
|
|
||||||
**Guides for migrating between different engine versions of the plugin:**
|
|
||||||
|
|
||||||
View the patch notes at www.vreue4.com for migration guides as well.
|
|
||||||
|
|
||||||
**Option 1:**
|
|
||||||
|
|
||||||
Go to www.vreue4.com and downloaded the pre-built binary version for the engine version you are using (not updated with every daily change, only weekly or with large patches).
|
|
||||||
|
|
||||||
Install it into your ProjectName/Plugins Directory (Engine level hasn't worked since 4.25 or so when it stopped letting me reference other plugins when compiling for that).
|
|
||||||
|
|
||||||
**Option 2 (More up to date - preferred if possible):**
|
|
||||||
|
|
||||||
* Clone Or Download Zip and extract this repository to a folder named "VRExpansionPlugin" in your "ProjectName/Plugins" directory, create this directory if it is missing.
|
|
||||||
|
|
||||||
* Add the VRExpansionPlugin to your projects PublicDependencyModuleNames in the projects build.cs if you have c++ code included.
|
|
||||||
|
|
||||||
* IF you do not have c++ code, use the Add New button in the editor and add a blank c++ class to your project.
|
|
||||||
|
|
||||||
* Open up the generated project .SLN file and build the project from the build menu.
|
|
||||||
|
|
||||||
You need to have visual studio installed and follow the UE4 setup guide for it: https://docs.unrealengine.com/latest/INT/Programming/Development/VisualStudioSetup/
|
|
||||||
|
|
||||||
### How do I use it? ###
|
|
||||||
### How do I VR? ###
|
|
||||||
|
|
||||||
The template project contains use examples of most of the features of the plugin as well as locomotion modes, interaction methods, and basic multiplayer.
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue