Version 3.1 - July 26, 2017
What’s new in version 3.1?
*** Simplification of functions, most delays removed
- 2 versions: Steam/Lan and Oculus Avatars, single and multiplayer (experimental)
- VOIP over Oculus Network
- Find friend’s sessions on Oculus Network**
[SIZE=3]Files found on the OneDrive at [/SIZE]Microsoft OneDrive - Access files anywhere. Create docs with free Office Online. , and on GitHub at GitHub - ProteusVRpublic/ProteusTemplate: Single/Multiplayer VR Template for Touch/Vive Controllers and Avatars
Read the pdf file included! A 3.1 packaged version (non Avatars) is also found on the OneDrive.
So let’s have a conversation on the Oculus Network and the Avatars…
Using Oculus Network
Ø Plugins/Virtual Reality/Oculus Rift and Oculus Library must be selected
Ø Plugins/Online Platform/Online Subsystem Oculus must be selected
Ø GameInfoInstance/Oculus Network must be selected
Ø Each player must be connected to Oculus Home with a different account
Ø The file /Config/DefaultEngine.ini must contain the following changes:
*[OnlineSubsystem]
;DefaultPlatformService=Steam
DefaultPlatformService=Oculus
;bHasVoiceEnabled=true
PollingIntervalInMs=20
VoiceNotificationDelta=0.2
[OnlineSubsystemSteam]
bEnabled=false
SteamDevAppId=480
GameServerQueryPort=27015
bRelaunchInSteam=false
GameVersion=1.0.0.0
bVACEnabled=1
bAllowP2PPacketRelay=true
P2PConnectionTimeout=90
Achievement_0_Id=
[/Script/OnlineSubsystemSteam.SteamNetDriver]
;NetConnectionClassName=OnlineSubsystemSteam.SteamNetConnection
[OnlineSubsystemOculus]
;Enable this if using Oculus Network
;Then enter you app ID
bEnabled=true
OculusAppId=1111111111111111
[/Script/OnlineSubsystemOculus.OculusNetDriver]
NetConnectionClassName=OnlineSubsystemOculus.OculusNetConnection
[/Script/Engine.GameEngine]
!NetDriverDefinitions=ClearArray
; Uncomment the next line if you are using the Null Subsystem
;+NetDriverDefinitions=(DefName=“GameNetDriver”,DriverClassName=“/Script/OnlineSubsystemUtils.IpNetDriver”,DriverClassNameFallback=“/Script/OnlineSubsystemUtils.IpNetDriver”)
; Uncomment the next line if you are using the Steam Subsystem
;+NetDriverDefinitions=(DefName=“GameNetDriver”,DriverClassName=“OnlineSubsystemSteam.SteamNetDriver”,DriverClassNameFallback=“OnlineSubsystemUtils.IpNetDriver”)
; Uncomment the next line if you are using the Oculus Subsystem
+NetDriverDefinitions=(DefName=“GameNetDriver”,DriverClassName=“OnlineSubsystemOculus.OculusNetDriver”,DriverClassNameFallback=“OnlineSubsystemUtils.IpNetDriver”)
*
The 16-digits App ID is your Oculus App ID found in your App Oculus dashboard URL (i.e. https://dashboard.oculus.com/application/111111111111111/build). For more information on publishing your game on Oculus platform see https://developer3.oculus.com/documentation/publish/latest/ .
IMPORTANT:
Ø Plugins/Virtual Reality/Steam VR must be deselected
Ø Plugins/Online Platform/Online Subsystem Steam must be deselected
Ø **In AvatarMaster/Set Boundaries for Chaperone & Guardian, delete the functions related to SteamVR Chaperone, Vive Tracker and TrackerSpace RepNotify
****OCULUS AVATARS
**
Ø Use the Template, Oculus Avatar Version (latest is 3.1)
Ø All previous considerations related to using Oculus Network still apply
Ø **In MainMenuPC, Using Oculus Subsystem AND Using Oculus Avatar must be selected
**
**Put the following in DefaultInput.ini:
**
*+ActionMappings=(ActionName=“AvatarLeftTrigger”,Key=MotionController_Left_Trigger,bShift=False,bCtrl=False,bAlt=False,bCmd=False)
+ActionMappings=(ActionName=“AvatarRightTrigger”,Key=MotionController_Right_Trigger,bShift=False,bCtrl=False,bAlt=False,bCmd=False)
+ActionMappings=(ActionName=“AvatarLeftGrip1”,Key=MotionController_Left_Grip1,bShift=False,bCtrl=False,bAlt=False,bCmd=False)
+ActionMappings=(ActionName=“AvatarRightGrip1”,Key=MotionController_Right_Grip1,bShift=False,bCtrl=False,bAlt=False,bCmd=False)
+AxisMappings=(AxisName=“MoveForward”,Key=W,Scale=1.000000)
+AxisMappings=(AxisName=“MoveForward”,Key=S,Scale=-1.000000)
+AxisMappings=(AxisName=“MoveForward”,Key=Up,Scale=1.000000)
+AxisMappings=(AxisName=“MoveForward”,Key=Down,Scale=-1.000000)
+AxisMappings=(AxisName=“MoveForward”,Key=Gamepad_LeftY,Scale=1.000000)
+AxisMappings=(AxisName=“MoveRight”,Key=A,Scale=-1.000000)
+AxisMappings=(AxisName=“MoveRight”,Key=D,Scale=1.000000)
+AxisMappings=(AxisName=“MoveRight”,Key=Gamepad_LeftX,Scale=1.000000)
+AxisMappings=(AxisName=“TurnRate”,Key=Gamepad_RightX,Scale=1.000000)
+AxisMappings=(AxisName=“TurnRate”,Key=Left,Scale=-1.000000)
+AxisMappings=(AxisName=“TurnRate”,Key=Right,Scale=1.000000)
+AxisMappings=(AxisName=“Turn”,Key=MouseX,Scale=1.000000)
+AxisMappings=(AxisName=“LookUpRate”,Key=Gamepad_RightY,Scale=1.000000)
+AxisMappings=(AxisName=“LookUp”,Key=MouseY,Scale=-1.000000)
+AxisMappings=(AxisName=“MoveForward”,Key=MotionController_Left_Thumbstick_Y,Scale=-1.000000)
+AxisMappings=(AxisName=“MoveRight”,Key=MotionController_Left_Thumbstick_X,Scale=1.000000)
+AxisMappings=(AxisName=“AvatarLeftTrigger”,Key=OculusTouch_Left_Trigger,Scale=1.000000)
+AxisMappings=(AxisName=“AvatarRightTrigger”,Key=OculusTouch_Right_Trigger,Scale=1.000000)
+AxisMappings=(AxisName=“AvatarLeftIndexPointing”,Key=OculusTouch_Left_IndexPointing,Scale=1.000000)
+AxisMappings=(AxisName=“AvatarRightIndexPointing”,Key=OculusTouch_Right_IndexPointing,Scale=1.000000)
+AxisMappings=(AxisName=“AvatarLeftThumbUp”,Key=OculusTouch_Left_ThumbUp,Scale=1.000000)
+AxisMappings=(AxisName=“AvatarRightThumbUp”,Key=OculusTouch_Right_ThumbUp,Scale=1.000000)
+AxisMappings=(AxisName=“AvatarLeftTriggerAxis”,Key=MotionController_Left_Trigger,Scale=1.000000)
+AxisMappings=(AxisName=“AvatarRightTriggerAxis”,Key=MotionController_Right_Trigger,Scale=1.000000)
+AxisMappings=(AxisName=“AvatarLeftGrip1Axis”,Key=MotionController_Left_Grip1,Scale=1.000000)
+AxisMappings=(AxisName=“AvatarRightGrip1Axis”,Key=MotionController_Right_Grip1,Scale=1.000000)
+ActionMappings=(ActionName=“AvatarLeftFaceButton1”,Key=MotionController_Left_FaceButton1,bShift=False,bCtrl=False,bAlt=False,bCmd=False)
+ActionMappings=(ActionName=“AvatarRightFaceButton1”,Key=MotionController_Right_FaceButton1,bShift=False,bCtrl=False,bAlt=False,bCmd=False)
+ActionMappings=(ActionName=“AvatarLeftFaceButton2”,Key=MotionController_Left_FaceButton2,bShift=False,bCtrl=False,bAlt=False,bCmd=False)
+ActionMappings=(ActionName=“AvatarRightFaceButton2”,Key=MotionController_Right_FaceButton2,bShift=False,bCtrl=False,bAlt=False,bCmd=False)
*
**SINGLE PLAYER AVATAR **
Ø In MainMenuPC, Is Single Players should be selected
· Use MainMenuGM as game mode and GameInfoInstance on all maps
**MULTIPLAYER - EXPERIMENTAL **
Connect the same way as Steam
Steam can still be running, do not interfere with process
LAN doesn’t work with Avatars
Multiplayer mode is experimental.
What works for now: VOIP, spawning local and remote Avatar
What still doesn’t work: remote Avatars are still controlled by each locally-controlled player.
How the Avatars Works
The appearance of every person’s avatar is stored in his or her Oculus user profile as an Avatar Specification. The Avatar Specification identifies the meshes and textures that make up a person’s avatar. Before we retrieve this specification data, we have to initialize both the Platform SDK and the Avatar SDK using our app ID. Avatar Specifications are indexed by Oculus user ID. An app has easy access to the Oculus user ID of the currently logged in user. Template uses a third-person avatar which depicts hands, body, and base cone.
When logging in, the Oculus ID and Entitlement are fired in the MainMenuPC, the Oculus ID and name are sent to GameInfoInstance. When the menu widgets spawn, they retrieve this information. The host then starts and register in a map. Other clients go through the SteamLan widget. This widget relies on OculusLogin c++ class to find an Oculus session. Note that only friends that have installed the game (or registered beta users) will appear.
When spawning in a level, each player spawns 4 avatars: 1 for himself (AvatarMaster, based on ProteusLocal), and 3 AvatarRemote, based on ProteusRemote: 1 remote for the locally-controlled listen-server, 1 remote for the pawns, and it also make previously spawned clients to fire a copy of the non-locally controlled remote Avatar. In the AvatarMaster pawn, the VOIP is also enabled.
How Avatar is rendered (from Oculus):
· Retrieve the avatar specification for the Oculus user
· Set the Avatar capabilities
· Iterate through the avatar specification to load the static avatar assets (mesh and textures) into the avatar.
· Apply the vertex transforms to determine the position of the avatar component.
· Apply the material states to determine the appearance of the avatar component.
· For each render part of an avatar component:
· Get the OpenGL mesh data and tell the renderer to use the Avatar shader program you compiled earlier.
· Calculate the inputs on the vertex uniforms.
· Set the view position, the world matrix, the view matrix, and the array of mesh poses.
· Transform everything in the joint hierarchy.
· Set the material state.
· Draw the mesh, depth first so that it self-occludes.
· Render to the color buffer.
· When there are no more components to render, the avatar render is complete.
Controlling the Remote Avatar – Still in development
Each player spawns a copy of Remote Avatar for each other players, and this copy is attached and possessed by these players. For this version, all Remote are driven by the inputs and transforms originating from the locally-controlled authority or client. The avatar packet recording system saves avatar movement data as packets: each time a packet is recorded, our code places the packet into a memory stream we are using as a stand-in for a real network layer. The remainder of our code receives the packet from the memory stream and plays it back on our loopback avatar object.
I’m working now on sending this data stream not to the memory buffer and back, but through the network to other players. Other avenue would be to use another copy of ProteusLocal, duplicate local inputs and transforms and send these back to the Avatar copies spawned by other clients.
**Opening the Avatar Project
**
Ø You must have Visual Studio 2015 or 2017 properly installed
Right-click on .uproject/Generate Visual Studio Project files
Click on .uproject; required files should then be created.
If it doesn’t work, open the .sln file with Visual Studio, rebuild the project, then you can open the project.
Packaging Avatars Project
Check the following options:
Packaging/Include Prerequisites
Packaging/Share Material Shader Code
Packaging/Share Material Native Librairies
Packaging/Include List of Maps to include in a packaged build (select your maps)
Additional Asset Directories to Cook/select the Content/Avatars directory
Side Note:
I’ve added “Oculus Network Delays” when using Oculus Network, because it is painfully needed. You can remove them on Steam / LAN.
Also: I’ve left many debug functions like my my debug cube and test pawn. The first was intensively used as a fake Avatar when developing without being connected (read: working in the countrysisde with my laptop beside a lake); the latter was also intensively used for replication testing.
I’ve left them here because they can be handy, but it would take you a big 5 minutes erasing their related functions and variables.
So I’ve just a little stretch do do before enabling full avatar remote control (read: hooking Oculus data stream through the Oculus network)
Please give me feedback and enjoy summer!!!