This page explains our implementation of object mapping in Unreal. For a high level overview of Tobii’s G2OM, check out the object mapping page.

When G2OM is referenced in the Unreal SDK code, it is currently referred to as “GTOM”.

How to use Tobii G2OM

Using G2OM in UE4 is quite simple. You just need to do two things to get started. First you need a GazeFocusManager. We recommend adding one of these components to your player controller, but you are free to put it wherever you want. This will be your access point for getting focus data. After this is set up, you just need to mark the objects in the world you want to be gaze focusable. There are two ways you can do this in UE4.

G2OM Component tags

The first one is using component tags. Just adding a tag called GazeFocusable to any primitive component will make that component participate in G2OM.

You can also customize some aspects of G2OM using other tags. All of them are listed in TobiiGTOMTypes.h, or you can see them here:

class TOBIIGTOM_API FTobiiGazeFocusTags
	// A primitive component with this tag currently has gaze focus.
	static FName HasGazeFocusTag;

	// A primitive component with this tag will participate in G2OM
	// even if the actor owning the primitive doesn't have a
	// GazeFocusableComponent, or if the default for the gaze focusable is off.
	static FName GazeFocusableTag;

	// A primitive component with this tag will not participate in G2OM
	// even if the actor owning the primitive component has a GazeFocusableComponent.
	static FName NotGazeFocusableTag;

	// A primitive component with this tag will modify it's priority.
	// Priority is used when only a certain number of focusables can
	// participate in an operation. An example of this is ID buffer
	// based GTOM. This is an argument tag, this means you must provide
	// the value after the tag. Usage example: GazeFocusablePriorityTag 100
	static FString GazeFocusablePriorityTag;

	// A primitive component with this tag and has the GazeFocusableTag will
	// only be considered if the distance between the G2OM source and the
	// component is shorter than the argument part of the tag. Please note
	// that this tag cannot be used to force the G2OM line traces to be longer
	// than default, only exclude the primitive if the distance is longer than
	// this argument. This is an argument tag, this means you must provide
	// the value after the tag. Usage example: GazeFocusableMaximumDistanceTag 10000
	static FString GazeFocusableMaximumDistanceTag;

	//A focus manager can opt to only query a subset of focusables by using
	// a focus layer. A primitive will this tag will only be subject to the
	// layer supplied as the argument. This is an argument tag, this means
	// you must provide the value after the tag. Usage example: GazeFocusableLayerTag Enemies
	static FString GazeFocusableLayerTag;

The HasGazeFocusTag is a bit special in that it is actually applied by the G2OM system to let you poll whether a primitive component has focus or not directly on the component. The reason why some tags are FString instead of FName is that they are so called “argument tags”. That means that to properly use them, you have to provide an argument as part of the tag.

If you for example would like a particular primitive component to have a different maximum range, you can use the GazeFocusableMaximumDistanceTag tag like so:

GazeFocusableMaximumDistanceTag 1000.

This would cause the primitive component to only participate in G2OM if it is within 10 meters of the player.

Gaze Focusable Components

The second way to mark something as gaze focusable is to use GazeFocusableComponents.

These can be added to any actor and will modify the default gaze focusability of every primitive component on the actor, acting as a sort of “default”. It of course offers all of the same functionality as the G2OM component tags do.

Using both G2OM component tags and gaze focusable components at the same time also works, and is in fact recommended. If a primitive component is affected both by a gaze focusable component and G2OM tags, the tags will take priority, overriding the default values from the gaze focusable component.

It is worth mentioning that while attaching gaze focusable components to actors that should be focusable in some way is strictly not necessary, we strongly recommend doing it for future proofing. Some types of low level G2OM might need them to run custom code on the actor, so if you don’t put them on every gaze focusable actor, you might have to update your code in the future if you want to start using these more powerful forms of G2OM.

Gaze Focusable Widgets

UI widgets are of course also objects that a user might want to focus, but since UI elements are not actors, or primitive components, we cannot use our tag, or component to mark them for focus. As such, we support UI gaze focus using something called GazeFocusableWidgets. These exist both in slate and in UMG, but the slate API is not fully featured yet.

  1. The radial menu here is an example type that we provide showing how to integrate other slate widgets with GazeFocusableWidgets. Feel free to remix this.
  2. Here you can see a gaze focusable widget wrapping some content (in this case a border element). This means that the border (and its children) will participate in G2OM.
  3. Gaze focusable widgets come with built in CleanUI that is configurable using these properties.

Please note that gaze focus using widget G2OM currently only works on world space widgets hosted in a WidgetComponent. The CleanUI still works in screen space however. As screen space widgets are strongly recommended against in XR though, this will probably not impact you much.

Focus Manager Layers

Focus managers can be configured to only consider subsets of scene objects. This can be very useful if you have multiple mechanics that act on different subsets of your scene actors.

One example could be a game where you have two types of enemies; robots and insects. Let’s then assume you have a pistol and hacking spells. The pistol should target both the insects and the robots, while the hacking spells should only target the robots. In this situation, if you only had one focus manager that produced one focus candidate, if that focus candidate ended up being an insect, your hacking spells would most likely not work as expected in some scenarios.

Since you can poll all of the focus candidates from a focus manager, you can of course just leave all gaze focusable objects in the default layer and then iterate the focused actors yourself, but it is easier to just use the focus layers since it allows for more complex subsets.

You can specify what layer a primitive component is in either by using the GazeFocusableLayerTag, or using a gaze focusable component with a default layer. You can then add your layer requirements to your focus manager either via white list (only allows primitive layers that are in the list) or via black list (excludes primitive layers that you specified from focus).