Develop
Develop
Select your platform

Using a Spatial Editor project with Spatial SDK

Updated: Mar 4, 2026
This guide outlines the steps to integrate Spatial Editor projects with Spatial SDK apps. Once integrated, your Spatial Editor project will be located in the scenes directory of your Spatial SDK app:
The scenes folder in a Spatial SDK project.

Set up the Spatial SDK Gradle plugin

The Spatial SDK Gradle plugin is used to process your Spatial Editor project and export it so it can be used by your app. Meta collects telemetry data from the Spatial SDK Gradle Plugin to help improve MPT Products. You can read the Supplemental Meta Platforms Technologies Privacy Policy to learn more.
To get started, ensure you have the following:
  • Android Studio installed.
  • A new Android Studio Spatial SDK project created, ideally using a starter sample as a template.
  • Spatial Editor installed, which includes the Spatial Editor CLI for export tasks.
Next, with your project open in Android Studio:
  1. Open the project’s libs.versions.toml file.
  2. In the [plugins] block, add the Meta Spatial Plugin.
     meta-spatial-plugin = { id = "com.meta.spatial.plugin", version.ref = "spatialsdk" }
    
  3. In app/build.gradle.kts, add the following to the plugins block:
     plugins {
       alias(libs.plugins.meta.spatial.plugin)
     }
    

Running Gradle tasks

Find the tasks available with the plugin in the Gradle sidebar under the spatial directory. Open the Gradle sidebar by clicking on the Gradle icon in the right sidebar of Android Studio. Android Studio may not configure all Gradle tasks by default. To configure all Gradle tasks so you can see and run them, enable Configure all Gradle tasks during Gradle Sync in File > Settings> Experiemental under the Gradle header. All Gradle tasks can be found under Tasks/spatial.
Gradle tasks in Android Studio.
To execute any of the tasks, either double-click them in the Gradle sidebar or run ./gradlew _task name_.

Export Spatial Editor projects

To prepare your Spatial Editor project for use in your Spatial SDK project, modify the build.Gradle file as follows:
val projectDir = layout.projectDirectory
val sceneDirectory = projectDir.dir("scenes")
spatial {
 allowUsageDataCollection = true
 scenes {
   exportItems {
     item {
       projectPath.set(sceneDirectory.file("Main.metaspatial"))
       outputPath.set(projectDir.dir("src/main/assets/scenes"))
     }
   }
  }
}

  • CliPath.set(...): the CLI executable’s location. If not set, the plugin will search predefined locations and may fail if the CLI is not found.
  • exportItems: Defines a list of projects and asset directories to be exported.
Ensure you replace the placeholder with the correct path to the Spatial Editor executable on your system.

Make custom components available in Spatial Editor

Spatial SDK projects use components for data storage. There are two ways to make custom components available in the Spatial Editor UI.

Define components in XML

Add a component XML file in app/src/main/components. The Spatial Editor will read the XML defined in the folder and display your custom components in UI. If you prefer to use another directory, refer to Specify the custom components folder.

Define components in Kotlin (removed)

In SDK versions prior to v0.10.1, a generateComponents Gradle task was available for Kotlin-defined components to synchronize the component definition over to Spatial Editor (so Spatial Editor could recognize these components). This task has been removed — component generation from XML is now automatic at build time. Define your components using XML in app/src/main/components as described above.

Load and change between compositions

The following sample demonstrates how to change between two compositions (Composition1 and Composition2) when a UI button is pressed (button0):
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    ...
    loadGLXF("Composition1")
}

override fun registerPanels(): List<PanelRegistration> {
    return listOf(
        LayoutXMLPanelRegistration(
            registrationId = R.id.ui_example,
            layoutResourceIdCreator = { R.layout.ui_example },
            settingsCreator = {
                UIPanelSettings(
                    shape = QuadShapeOptions(width = 2.0f, height = 1.5f),
                )
            },
            panelSetupWithRootView = { rootView, _, _ ->
                rootView.findViewById<Button>(R.id.button0)
                    ?.setOnClickListener { loadGLXF("Composition1") }
                rootView.findViewById<Button>(R.id.button1)
                    ?.setOnClickListener { loadGLXF("Composition2") }
            }
        )
    )
}

private fun loadGLXF(compositionName: String): Job {
    gltfxEntity?.destroy()
    gltfxEntity = Entity.create()
    return activityScope.launch {
        glXFManager.inflateGLXF(
            Uri.parse("apk:///scenes/${compositionName}.glxf"),
            rootEntity = gltfxEntity!!,
            keyName = compositionName)
    }
}

Target specific objects in a composition with logic

The following example shows how to target a specific node of your composition (environment) with logic (adjusting the visibility):
loadGLXF().invokeOnCompletion {
    val composition = glXFManager.getGLXFInfo("example_key_name")
    val environmentEntity = composition.getNodeByName("Environment").entity
    environmentEntity?.setComponent(Visible(false))
}

private fun loadGLXF(): Job {
    gltfxEntity = Entity.create()
    return activityScope.launch {
        glXFManager.inflateGLXF(
            Uri.parse("apk:///scenes/Composition.glxf"),
            rootEntity = gltfxEntity!!,
            keyName = "example_key_name")
    }
}

Populate a panel using Spatial SDK

When populating panels using Spatial SDK, you can differentiate them by setting a unique ID in the Properties panel of Spatial Editor. The ID should reference an ID resource (R.id.panel_name) rather than a layout resource, as the layout is specified separately in the registration.
Here are several methods to layout and define panel content:
  • Use LayoutXMLPanelRegistration to define panel UI using layout XML.
  • Use ActivityPanelRegistration to define panel UI using an Activity.
  • Use IntentPanelRegistration to define panel UI using an Intent (allowing you to pass information along to your inflated Activity).
  • Use ViewPanelRegistration to define panel UI using a View at runtime.
For example, this script populates a small panel using Jetpack Compose:
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

@Composable
fun MyPanel() {
    Column(modifier = Modifier.padding(16.dp)) {
        Text(text = "Panel Title", style = MaterialTheme.typography.headlineSmall)
        Spacer(modifier = Modifier.height(8.dp))
        Text(text = "This is a panel with some content")
    }
}
For an in-depth look at populating panels with 2D content, see the Spatial SDK panel documentation.
Did you find this page helpful?