Content Template


  1. 1.
    Do a fresh clone/fork of ‘Content Creator Template’ repository
  2. 2.
    Open cloned project in Unity 2021.3.8f
  3. 3.
    Navigate to ‘Assets/Scenes’ folder and create a new Scene
  4. 4.
    Rename it to something that makes sense for you (For now, you are free to choose a name for scene, but in further releases scene name will be provided to you through platform)
  5. 5.
    In opened scene, navigate to top menu, and find Morpheus Tools tab, in drop-down menu select Setup Scene, as it shows in the screenshot below
5.1 Setting up the scene in Unity
3 Main elements will be added to your scene. All objects that were a part of the scene before Setup Scene command execution, will be moved under Environment game object.
4.2 Setting up the scene in Unity
  • Physics Simulator - network object, for synchronization of Rigidbody objects
  • StartPosition - Zone spawning object that is already set as a reference in Zone Info. Feel free to drag it where you wish users to spawn.
  • ZoneInfo - Zone information container
    • Skybox Material - Skybox material should be cached here, to overwrite default skybox of Morpheus application.
    • Default Start Position - Start Position of users. User avatars will spawn on this coordinates after loading. Remember that Z axis of this object, represent where user will initially look at.
    • Default Landing Zone - Landing Zone of users. User avatars will spawn in this zone after teleporting with portal. Remember that Z axis of this object, represent where user will initially look at.
  • Environment - All decoration object of scene are stored here
5. Now you are free to edit and decorate your scene, as you used to do in regular scenes.

Landing Zones

A landing is an entry point into a zone, now they will be defined within the zone instead of portals.
Currently, only a circular landing has been implemented. When entering the zone through this landing, users will spawn at a random point inside this circle, depending on the Z-axis of the landing object.
To use it, you need to create an empty object and add the RoundLandingZone script to it, assign a unique name to the landing for this zone, and modify the Radius parameter.
Also, in the ZoneInfo, in the Default Landing Zone field, you need to enter the name of the default landing if, for some reason, no landing is specified for the portal. If something goes wrong with the default landing as well, the player will spawn at the Default Start Position.


  1. 1.
    Select all object that are meant for users to move on them. (It is recommended to create them as a separate “hidden” object, with only colliders)
  2. 2.
    Select ‘Morpheus Tools’ tab, and select ‘Add Teleportation Area', command as it is showed in screenshot
2.1. Adding teleportation area
3. On selected objects, component ‘Teleportation Area’ will appear that will allow users to move on them.
Important : Each object that carries ‘Teleportation Area’ component, should have at least one ‘Collider’ component. It can on selected object, or on one of child objects.
Additional Information: You can find an ‘Objects’ layer already defined in project. ‘Objects’ layer objects will allow users to teleport through them, but Rigidbody objects will collide with them. (Example. Tables, Chairs, etc.)


For nice and smooth lighting, it should be baked through ‘Bakery’ instrument. For baking, use parameters as it is shown in screenshots.
If results are not as satisfying as you want, read Manual to Bakery for more details.


To use a custom skybox, instead of default one, you should find an object in scene called ‘ZoneInfo’. Replace material reference ‘Skybox Material’ to your custom skybox material.
If you want to apply current opened scene’s skybox, click on ‘Apply Skybox’ command in ‘Morpheus Tools’ tab.
Applying Skybox

Occlusion Culling

Occlusion Culling - Occlusion culling is a process which prevents Unity from performing rendering calculations for Game Objects. In Unity it isn’t done automatically . In project ‘Content Creator Template’ there are two tag realizations of ‘Occlusion Culling’:
  • Occludee
  • Occluder
‘Occluder’ layer object can hide ‘Occludee’ layer object, but they will not hide on their own. ‘Occludee’ layer objects can hide other layer object, but they can hide too, if they are hidden by other ‘Occludee’ or ‘Occluder’ layer object. Other layer objects behave outside of Occlusion Culling logic, they never hide themselves or other objects. If object is in layer ‘Occludee’ and is using component ‘LODGroup’, that it will hide objects through ‘LOD0’ mesh.
Important: 3D model assets, that are used in culling process, should have ‘Read/Write’ enabled. Example in screenshot.

Builds ⚙

  1. 1.
    Enter to the menu, through top panel ‘Window/Asset Management/Addressables/Groups’ and delete demo scene object
  2. 2.
    Select your scene in ‘Project’ and set ‘Addressable’ checkbox in ‘Inspector’ view, as it is shown in screenshot
Selecting addressable for the build
3. Navigate to ‘File/Build Settings’ and select one of three platforms
  • ‘Android 32bit’
  • ‘iOS’
  • ‘Linux’ (Not Dedicated Server)
  • ‘Windows’ (Not Dedicated Server)
  • ‘Mac’ (Not Dedicated Server)
After that, platform switching process will trigger, that can take a while, based on project assets amount and size
4. Return to ‘Addressables Groups’ and on top panel of window press ‘Build/New Build/Default Build Script’, after processing, in projects folder ‘Content-Creator-Template/ServerData’ ‘BuildTarget’ folder will be created. You can find bundle files there
5. Repeat 3 and 4 points for other 2 platforms left
6. Navigate to ‘ServerData’ folder, and select all three folders (‘Android’, ‘iOS’ и ‘StandaloneLinux64’), and create a ‘.zip’ archive
7. You can upload archive through Geometry Data panel in Admin Panel.

Interactivity Package

Package Installation
  1. 1.
    Open the Window/Package Manager.
  2. 2.
    Click the '+' button, and in the dropdown menu, select "Add Package from git URL..."
  3. 3.
    Paste the repository address of the package: https://github.com/morpheusxr/com.morpheusxr.platform.interactivity.git
  4. 4.
    Click "Add" and wait for the import process to complete.
Importing Examples:
  1. 1.
    Open the Window/Package Manager.
  2. 2.
    In the package information for Interactivity, there is a list of Samples, allowing you to import the desired examples into your project.
Presence Map / Interactive VFX:
To receive information about the presence of objects (both users and artifacts) inside a VFX, you need to create a zone of influence on the VFX using the ObjectsPresenceZone component.
Parameters to configure:
  • Add the target VFX in the scene to the AffectedVfx list.
  • Set up the Bounds - the presence tracking will work within the Bounds of this zone, so it should match the volume where the VFX particles reside. Displayed as a yellow gizmo-box in the scene view.
  • Set the ObjectsRadius parameter - the approximate size of the expected objects, defining the zone of maximum interaction around the object's pivot. The "presence" characteristic within this radius will be equal to 1.0. A good value for effects reacting to the user "in general" is 0.25.
  • Set the PresenceRadius parameter - the distance from the object's edge (after adding ObjectsRadius) where the "presence" characteristic will drop to 0.0.
  • MapResolution affects the system's resolution, meaning the higher the map resolution, the closer the system can distinguish objects in theory. However, significantly increasing this parameter is not recommended, as high resolutions can negatively impact performance.
In the VFX itself, you need to create two parameters (name matters, as the system will try to pass calculated data to the effect):
  1. 1.
    WorldToUVMatrix of type Matrix4x4.
  2. 2.
    PresenceMap of type Texture2D.
To obtain information about the nearest object, do as follows:
(Copy this block from the SampleInteractiveVFX effect in the sample scene included in the package; when you paste it, both necessary parameters will be created.)
As a result, on the right, the xyz components contain the world-space position of the nearest tracked object, and the w component contains the calculated "presence" characteristic, which equals 0 at a distance ≥ [ObjectsRadius] + [PresenceRadius] and 1 at a distance ≤ [ObjectsRadius].
After that, you can use this information to modify the behavior or appearance of particles. You can see an example of such usage in the effect in the package's "Interactive VFX Sample" sample.
Triggers: This is a set of universal components (currently 2) that allow you to handle events when entering or exiting triggers. It requires a collider set to IsTrigger mode.
The events work only locally. To send events to other users, you should use the NetworkInvoke component in conjunction.
  • BasicTrigger: Simply triggers Unity events:
    • OnTriggerEntered: Triggered every time an object enters the trigger.
    • OnTriggerExited: Triggered every time an object exits the trigger.
    • OnHasObjectsInTrigger: Triggered when the first object enters the trigger.
    • OnNoObjectsInTrigger: Triggered when the last object exits the trigger.
  • SwitchTrigger: It enables the objects in the list when the first object enters the trigger and disables them when the last object exits. You can invert the logic with the "Invert" checkbox.
NetworkInvoke: If you need an event to occur for all users, you should use the NetworkInvoke component. It integrates into the event chain.
In the case of local application, the chain looks like this: User (client A) → BasicTrigger / Interactable (client A) → Animator (client A) Other clients will not receive the event.
With NetworkInvoke, the event is transmitted to all clients through the server: User (client A) → BasicTrigger / Interactable (client A) → NetworkInvoke (client A) → network magic → NetworkInvoke (server) → network magic → NetworkInvoke (all clients) → Animator (all clients)
To make it work:
  1. 1.
    Add the NetworkInvoke component to some object in the scene (it will automatically add the NetworkIdentity component needed for synchronization).
  2. 2.
    Create an event in the Events list, assign it a key (by default, the component is created with one event with the key "run").
  3. 3.
    At the event source, e.g., BasicTrigger, add an object with NetworkInvoke to the event, select the InvokeEvent method, and specify the name of the required event in the string.
  4. 4.
    In the NetworkInvoke component, add a reaction to the event.
    1. 1.
      For locally played effects (e.g., playing sound through AudioSource), use the OnClientsInvoke event, which will be called on each client (but not on the server).
    2. 2.
      For objects that synchronize themselves on the server (e.g., using the NetworkAnimator component), use the OnServerInvoke event, which will be called only on the server.
In addition to BasicTrigger, you can use the XRSimpleInteractable component as an event source. Clicking on an object with this component or grabbing it will trigger the SelectEntered event. To do this, the object with this component must be in Layer #18 and have a convex collider.