Adding teleportation area to Cesium tilesets using XR Interaction Toolkit

Hi there, any idea how to make Cesium terrains teleportable? I’ve added teleportation area script, mesh collider/box collider, set up correct layer, but can’t make it work.

Can you describe what you mean by teleportable? Do you mean moving the terrain (changing its transform) at runtime?

I am building a VR app with XR interaction toolkit, so I would like my XR origin (avatar) to be able to move around the terrain quickly using teleportation. Right now I can only move slowly using joysticks. As I mentioned above, I set everything up as I normally do for other ground objects, added teleportation area script to “Cesium World Terrain” and it is set to Default layer, as all my other teleportation components in the right and left controllers. But it does not allow me to teleport on top of the terrain.

Hm, I’m not personally familiar with the XR interaction toolkit but I’ll see if I or someone else can look into it. Can you just confirm that you have “Create Physics Meshes” enabled on Cesium World Terrain? It won’t generate mesh colliders otherwise.

Yes, it is enabled by default. Thanks and hope we can get it solved.

Hi @VRTravelExpo,

We just released Cesium for Unity 1.4.0, which includes this PR: Added event to notify when new GameObject is created. by joseph-kaile · Pull Request #336 · CesiumGS/cesium-unity · GitHub

To summarize, we added a Cesium3DTileset.OnTileGameObjectCreated event, which allows you to modify the tile game objects after they’ve been created. This allows you to do something like so:

tileset.OnTileGameObjectCreated += go  => go.AddComponent<TeleportationArea>();

With that, you should be able to teleport to parts of Cesium World Terrain.

1 Like

Thanks, but could you please provide more specific guidance on where and how to implement the suggested line of code cesium3DTileset.OnTileGameObjectCreated += go => go.AddComponent<TeleportationArea>(); ? Where exactly in my project should this code snippet be added? Do I need to manually add the TeleportationArea script to the Cesium World terrain, or do I have to create an empty parent GameObject and create a script containing this line of code? Please, clarify.

Thanks,
Evgeniya

You don’t need to add a TeleportationArea to the tileset itself. The TeleportationArea is added to the tiles using that line of code.

This is an open-ended question and there’s no “right” answer. You just need some object with a script that has this line of code before the game starts, for example in Awake() or Start(). You can make the tileset variable a parameter, and have it reference the desired tileset. Whatever file you put this code in is up to you.

Thank you for your clarifications. However, I am still unsure about the exact class or type of my Cesium tileset in Unity. There are no scripts attached to the Cesium World terrain for me to inspect and find the class type. Could you please inform me what the class or type name I should use to reference my Cesium tileset in a script? I understand from your previous response that I need to add a listener to the OnTileGameObjectCreated event, but I’m not sure what object this event belongs to.

Additionally, you’ve mentioned a ‘desired tileset’. In my case, I aim to enable teleportation globally to all existing and future tilesets. Any additional guidance you can provide to help me locate this would be greatly appreciated.

Thanks,
Evgeniya

I would look into some basic Unity scripting tutorials to help you understand what’s going on. There is a script attached to Cesium World Terrain, or else it wouldn’t work. It’s the Cesium3DTileset script. It’s not modifiable, but it is the component that contains the OnTileGameObjectCreated event.

This is one potential solution but if you need to modify it in any way, it will help to learn how to write code for Unity.

Create a AttachTeleportationArea.cs script like so.

using CesiumForUnity;
using UnityEngine;

public class AttachTeleportationArea: MonoBehaviour
{
   // You can drag-and-drop the desired tileset into this variable in the Inspector.
   // But for demonstration's sake, this will assume that the script is attached to
   // a game object with a `Cesium3DTileset` component.
   public Cesium3DTileset tileset;

   void Awake() {
      tileset = gameObject.GetComponent<Cesium3DTileset>();
      if (tileset != null) {
         tileset.OnTileGameObjectCreated += go => go.AddComponent<TeleportationArea>()
      }
   }
}

Then attach it to the desired tilesets. In other words, attach it as a component to any tileset you want to have teleportation areas :slight_smile:

Thank you for your patience. The script was throwing errors, which I was able to resolve by adding using UnityEngine.XR.Interaction.Toolkit;. I’ve attached the AttachTeleportationArea script to the empty GameObject in my scene, and I’ve made sure to drag and drop the Cesium World Terrain (Cesium 3D Tileset) into the tileset slot in the Inspector.

However, I’m still unable to teleport my avatar within the scene. The avatar continues to move slowly, as before. Is there something else I need to configure or set up in order to enable teleportation? Any further guidance you can provide would be appreciated

Hello @VRTravelExpo , could you confirm that you have a Teleportation Provider in your XR Origin setup?

Yes, of course. Teleportation works fine when I use regular Unity terrain or simple plane and attach Teleportation area script from the XR Interaction Toolkit. I select interaction layer mask as “teleport.”

If you want to recreate this, you can use XR interaction toolkit example project with all of the necessary settings set up correctly GitHub - Unity-Technologies/XR-Interaction-Toolkit-Examples: This repository contains various examples to use with the XR Interaction Toolkit

In this package, there is also XR Device Simulator prefab to test it on the desktop.

Maybe it has something to do with the interaction layer mask.

The script above will set the Interaction Layer Mask to default. Maybe it needs to be set to “Teleport” via code.

Does your XR Ray interactor have the Interaction Layer Mask set to “Teleport”?

Changing Interaction Layer Mask to ‘Default’ inside my XR Origin prefab’s ‘Teleport Interactor’ didn’t do anything. Changing ‘Default’ layer to ‘Teleport’ inside Cesium game object also didn’t do anything, except for making me to fall through the floor, so I added a box collider. I was told not to add teleportation area script to Cesium game object, this is where I would normally change the layer mask to teleport if I want to turn that area into the floor for teleportation. So, I assume the line of code I was given earlier was supposed to communicate with my ‘Teleport Interactor,’ but I feel like something is missing. Does it really work when you are testing it?

Thanks,
Evgeniya

Yes it does work for me.

In Play Mode, when you select “Show Tiles In Hierarchy”, if you select a random tile, what does the Teleportation Area look like?

For instance:

On the script that’s added, you can see the Layer Mask is set to Default and also it added the Terrain Collider to its list of Colliders. Is that what you’re seeing?

When I use XR Device Simulator, line teleporter appears red, which means the area is not teleportable, I can walk, but I can’t jump quickly. Same when I test in in my VR headset. I see that you added Teleportation Area script, which I was told not to use earlier, because cesium3DTileset.OnTileGameObjectCreated += go => go.AddComponent(); is referencing it. But even if I do attach it, it does not change things.

Here is for your reference a screenshot using a regular unity terrain, where the line interactor is green and I am able to quickly jump wherever I want.


Thanks for the images.

I didn’t manually add the Teleportation Area script, that is the result of cesium3DTileset.OnTileGameObjectCreated += go => go.AddComponent();

IIn the picture, you have highlighted the Cesium World Terrain GameObject. What if you highlight one of the tiles? You should see the Teleportation Area script attached to each tile.