GEM Plugin Class Specification
GEM Structs and Enums¶
FPlayerInfo : This is a struct that contains info retrieved from GEM about the the player:
- Controller (APlayerController*): Pointer to the PlayerController for this player
- PlayerId (FString): The GEM User ID for this player
- PlayerHeight (float): The height of the player in meters. Set during the Client Startup Level. This should be retrieved and passed to the game server on client join.
- AvatarIndex (int): The index of the Avatar that this player should use (for experiences that support player selected avatars)
- LanguageCode (FString): The locale code for this player.
FGEMZoneDefinition: This struct contains everything to define a Section of the experience
- StageZoneIndex (int): The index of the Stage Zone that this section occurs in.
- ExpectedSectionTime (float): Time (in minutes) a group is expected to take in this section.
- Origin (ATrackingOrigin): The tracking origin the players should be attached to for this section.
- GameZoneBoundaries (Array of ZoneBoundaryVolumes): An open-ended array of game zone boundaries for this section.
- ExitVolume (ATransitionVolume): The exit volume for this section. Bridges the Stage Zone of this section with the Stage Zone of the next section.
- CurrentlyActiveGameZone (int): The index of the game zone from the GameZoneBoundaries array that is currently active.
FGhostData: Struct for received ghost data.
- Ghost (AActor*): Pointer to the spawned Ghost actor.
- LastUpdateTime(float): Timestamp for the last received update for this ghost. Used to determine the ghost's age and clean it up if no update has been received for over 10 seconds.
FGEMObstruction: Struct to define the bounding box of a dynamic obstruction. Essentially the same as an FBox2D.
- BoundsMin (FVector2D): The minimum point of the bounding box.
- BoundsMax (FVector2D): The maximum point of the bounding box.
EBoundsState: Enum of the player's current out of bounds state. The ClientExperienceComponent will fire the OnOutOfBoundsChange event when the bounds state changes:
- InBounds: The player is in bounds
- OutOfGameBounds: The player has left the bounds of the currently active Game Zone, but is still inside the currently active Stage Zone.
- InMultiGroupZone: The player is in-bounds, but the Stage Zone has been tagged as Multi-Group, so ghost position data should be sent for as long as the player is in this zone.
- OutOfZoneBounds: The player has left the bounds of the currently active Stage Zone.
- OutOfStageBounds: The player has left the stage entirely.
EExperienceEndState: Enum of the current end game state for the player. The ExperienceManagerComponent will fire the OnExperienceEnded event when the end state changes.
- BeginOffload: The experience has ended. The players should be informed that it has ended and to exit the stage.
- OffloadComplete: The player has exited the stage.
GEM Component Classes¶
ExperienceManagerComponent¶
This is a component that should be attached to the experience's GameState. This component handles the flow of users through the experience, as well as holding information about the current group and handling all communication with GEM.
Events¶
OnZoneStarted (int ZoneIndex, int Section): Fires when all players have entered a new Stage Zone, or after the currently active Transition Volume has timed out. Returns the Stage Zone Index and the Section Index of the newly started Zone.
OnZoneOpened (int ZoneIndex, bool IsFree): Fires when GEM returns the Get Is Zone Free call. Returns the index of the requested Stage Zone, and whether the Stage Zone is free or not.
OnExperienceEnded (EExperienceEndState EndState): Fires with BeginOffload when the end of the experience has been reached. Fires again with OffloadComplete when a player exits the stage bounds after the experience has finished.
OnReceivedEmergency(bool EnablePassthrough, FText EmergencyMessage): Fires when an emergency message has been received from GEM. If EnablePassthrough is true, you should take whatever steps are necessary to enable passthrough mode on the headset. EmergencyMessage is a localized FText, and should be displayed to clients.
OnReceivedStartTutorial(): Fires when GEM sends a Start Tutorial command. Any pre-experience tutorial should wait until this event is received before activating.
Functions¶
bool IsUsingGEMOSS: Helper function to check if the GEM Online Subsystem is the currently active Online Subsystem.
bool GetInBounds: Returns a simple true/false for whether the player is In Bounds or not.
FTransform GetOnboardTransform: Returns the worldspace transform for the Onboard Area, transformed by the transform of the current active Tracking Origin. If the onboard area is off of the stage, rotation/forward vector of the transform will point towards the stage, otherwise will be a Zero Rotator/ X-Forward vector. Can only be called from Authority/Server. If called from Remote/Client it will return an Identity Transform.
FTransform GetOffboardTransform: Returns the worldspace transform for the Offboard Area, transformed by the transform of the current active Tracking Origin. If the offboard area is off of the stage, rotation/forward vector of the transform will point towards the stage, otherwise will be a Zero Rotator/ X-Forward vector. Can only be called from Authority/Server. If called from Remote/Client it will return an Identity Transform.
AActor* GetActiveTrackingOrigin: Returns a pointer to the current Active Tracking Origin.
void StartNextGameZone: Activates the next game zone of the current section, and starts timing out the current game zone. If on the last game zone of the current section and the next section is still in the same Stage Zone, activates the first Game Zone of the next section, and attaches players to the Origin of the next section, keeping their relative positions. If the next section is not in the same Stage Zone as the current section, a call will be made to GEM to determine if that Stage Zone is free. If the next Stage Zone is free, the Exit Volume of the currently active section will activate, the currently active Game Zone of this section will begin to time out, and OpenNextStageZone will fire, returning True for bIsZoneFree. If the Stage Zone is not free, OpenNextStageZone fill fire returning False for bIsZoneFree, and then it will wait 10 seconds and try again.
void SetTutorialComplete(bool newComplete): Setter function for bTutorialComplete. Any in-game tutorial must set bTutorialComplete to True for the experience to continue. No OnZoneOpened or OnZoneStarted events will not fire until it is.
bool GetTutorialComplete: Getter function for bTutorialComplete.
Variables¶
FGEMZoneDefinition StartupSection: Since we don't (and can't) know every possible physical onboarding configuration, this is a section definition for a nebulous 'off stage' onboarding area. This only requires a Tracking Origin and an Exit Volume be defined.
TArray\<FGEMZoneDefinition> Sections: The array of Section definitions for the entire experience.
TArray\<FPlayerInfo> GroupInfo: Array of all the PlayerInfos for the current group.
FVector2D StageOffsetLocation: How far to offset the players from the center of the stage. Used to fine tune positioning of players in the experience when the calibration of the stage isn't 100% correct, or for artificially locomoting an entire group when testing in a space smaller than the target stage size (99.9% of the time you shouldn't ever have to touch this)
TArray\<FBox2D> StageZoneBounds: Array of the AABBs for the Stage Zones. Derived from the ZoneBoundaryVolumes in the world. Used to determine which Stage Zone a player is in if they are not in the currently active one. (99.9% of the time you shouldn't ever have to touch this)
ClientExperienceComponent¶
This is a component that should be attached to the experience's PlayerController. This primarily exists for routing RPCs to the Server, as the GameState is not owned by the Client, and thus the Client can't call an RPC on it, but it does have two important events.
Events¶
OnOutOfBoundsChange (EBoundsState OutOfBounds): Fires when the bounds state of the player changes. Should be used to control activation of Chaperone effects.
OnOffloadComplete: Fires when the client has finished offloading. Used to automatically disconnect the Client from the Server and destroy the Client Session.
GEM Actor Classes¶
These are the actors the GEM Plugin uses to map the experience in virtual space to the physical space. These should all be placed in either a persistent level, or an always loaded sub-level.
TrackingOrigin¶
This defines the center of the stage. All Player Pawns should be attached to a Tracking Origin.
Variables¶
int FloorSizeIndex: The index of the floor size array from the Group Experience Manager Plugin Settings that this tracking origin should use. (NOTE: At present, GEM will only support one floor size per experience, but in the future we hope to support multiple floor sizes in order to more easily support deployment to different sized venues)
ZoneBoundaryVolume¶
This defines the boundaries of a Game Zone. It can be any arbitrary size or shape that can be modeled in Unreal's Brush Editing Tools. A Zone Boundary Volume must be attached to a Tracking Origin.
Variables¶
int StageZone: The index of the Stage Zone that this Game Zone takes place in. The size and shape of a Stage Zone of a given index is derived from all of the Game Zones that are set to that index. Game Zones that are using the same Stage Zone index can (and often should) overlap. Stage Zones should not overlap.
bool bIsMultigroup: Tag whether the Stage Zone for this Zone Boundary Volume supports having more than one group occupying it at a time. When toggled, all Zone Boundary Volumes with the same StageZone index will update to the new setting. Also, when adding a new Zone Boundary Volume and assigning a Stage Zone Index, or re-assigning the stage zone index for an existing one, this setting will automatically inherit from any other Zone Boundary Volumes that are assigned to that Stage Zone Index.
float Timeout: Number of seconds before this Game Zone becomes inactive after activating the next Game Zone in this section, or the Transition Volume at the end of the section.
bool bIsActive: Whether or not this Game Zone is active (Note: Generally speaking this should be left alone. Activation and Deactivation of Game Zones is handled by the ExperienceManagerComponent)
TransitionVolume¶
This is used to define the safe area for moving from one Stage Zone to the next. It can be any arbitrary size or shape that can be modeled in Unreal's Brush Editing Tools. A Transition Volume must be attached to a Tracking Origin. Activation and deactivation is handled by the ExperienceManagerComponent.
Variables¶
float Timeout: Number of seconds before this Transition Volume becomes inactive. This timeout activates once at least one member of the group has entered the next Stage Zone. Once the timeout expires, the OnZoneStarted event will fire, regardless of whether all (or any) members of the group are in the next zone. Set this to -1 if you don't want the transition zone to time out at all.
StageDebugVisualizer¶
This is an Editor Only helper actor that is automatically created when adding any GEM Actor to the level. This handles drawing the bounds of the Stage and the Stage Zones local to any Tracking Origins in the world. Stage bounds will be drawn in blue, Stage Zone bounds will be drawn in green, unless the Stage Zone bounds exceed the bounds of the stage or overlap another Stage Zone, in which case they will be drawn in Red.
There is an Update Stage Visualization button to force redrawing the visualization if it appears to be out of date (this will usually occur if the Brush Editing tools have been used to edit the shape of a ZoneBoundaryVolume).
There are also two console commands to help with the visualization:
gdv.DrawCentered: Will draw a copy of the debug stage visualization centered at the world origin.
gdv.DrawOnTop: Sets the depth priority of the debug visualization. 0=Draw Normally, 1=Hide the visualization, >1=Ignore Depth
GEM Non-actor Classes¶
There are three important non-actor classes in GEM. Two in the GEMGameSystemsModule, and one in the main plugin module.
GEMGameSession¶
The Game Session class. Automatically handles registration of the Game Server with GEM. If you are using a custom Game Session class it must inherit from the GEMGameSession. If your Game Session class is overriding RegisterServer, it will not be compatible with the GEMGameSession. There are no accessible functions or variables in the GEMGameSession.
GEMGameInstance¶
The Game Instance class. Used to retain data retrieved from GEM during the Client Startup Level so it can be passed to the Game Server after joining. If you have a custom Game Instance, it must inherit from the GEM GameInstance.
Variables¶
All of these variables have Setter and Getter functions. You should only have to use the Getters.
FString PlayerId: The GEM UserID of the current player.
FString PlayerName: The name the player entered when they signed up.
float PlayerHeight: The height of the player in meters.
int AvatarIndex: The index of the Avatar that this player selected (in experiences that support player selection of Avatars)
FString LanguageCode: The locale code for this player.
Function(s)¶
FString GetDeviceID: Returns the DeviceId for the current device.
GEMPluginSettings¶
The plugin settings. Accessible under Edit->Project Settings->Plugins->Group Experience Manager. Used to define the stage size, which class to use for Ghosts, and some GEM metadata.
Editable Variables¶
TArray\<FVector2D> LocationSizes: The array of supported stage sizes for this experience (see previous note about support for multiple stage sizes). As Unreal is X-Forward, the larger dimension of the stage size should be X.
TSoftClassPtr\<class AActor> GhostClass: The Actor class to use as a Ghost for this experience. A Ghost is an abstract representation of a player from another group that is spawned when that player has intruded into another group's zone. The only requirements for a Ghost are that it be a replicated actor and that it have a visual representation that should be \~2 meters tall and \~1 meter wide (enough to fully encompass both a quite tall person, and a person in a wheelchair). Ghost's are only provided with simple positional data, so it is also recommended that the visual element have some amount of rotational symmetry.
TSoftObjectPtr\<UMaterialInterface> ObstructionMat: The material to use for dynamic obstructions. Since dynamic obstructions are representative of real-world physical obstructions that may be on the stage, it is recommended that this material both be an unambiguous warning color, but have some sort of depth fade so as to only become visible when there is a risk of a player colliding with it.
TArray\<FGEMObstruction> Obstructions: The array of dynamic obstructions. Do not set this in the project settings. As dynamic obstructions are unique to each location, they should be defined in the UserGEMSettings.ini of a packaged build, not the DefaultUserGEMSettings.ini of the project.
bool bAutoAttachPawns: Whether to automatically attach pawns to the active tracking origin on spawn and when tracking origin changes occur. Generally this should remain true, but there may be build targets where it is desirable to handle attachment manually, or forgo attachment altogether (i.e. non-VR builds, non-LBE builds).
bool bHasTutorial: Whether this experience has a tutorial or not. If the experience does not have a tutorial, OnZoneOpened for the first zone will fire as soon as the ZoneRequest is granted by GEM. If the experience does have a tutorial, OnZoneOpened for the first zone will not fire until bTutorialComplete has been set to True.
FString GEMAppName: The name of the app for GEM.
FString GEMAppVersion: The version of the app for GEM. If using the Wevr Studio Gitlab CI, this will be set automatically by the build process.
FTransform OnboardTransform: The relative transform of the onboard area, derived from the bounding box received from the RegisterServer return.
FTransform OffboardTransform: The relative transform of the offboard area, derived from the bounding box received from the RegisterServer return.
FString DeviceID: Can only be set by editing either DefaultUserGEMSettings.ini or UserGEMSettings.ini. Used to override the Device ID of the current device. Mostly used for testing on Windows when launching the project with the "-game" command line, as GetDeviceId doesn't return a valid device id on the Windows platform. Override string must contain an underscore. Device ID can also be overridden with the -DeviceID command line.
FString GEMServerIP (Deprecated): IP Address of the GEM Server on the local network.
int GEMServerPort (Deprecated): Port of the GEM Server.