Cesium for Unity Documentation

repository·main·Indexed 19 days ago

https://github.com/cesiumgs/cesium-unity

A plugin that brings the 3D geospatial ecosystem to Unity, enabling the creation of 3D geospatial applications by streaming real-world content like terrain, imagery, and 3D Tiles using open standards and the WGS84 coordinate system. It integrates with Cesium ion and provides tools for high-accuracy geospatial workflows, including a C# <-> C++ interop layer via Reinterop.

Tokens
5.3K
Snippets
16
Records
25
Agent score
68%

What's inside Cesium for Unity

  1. Supported Platforms Overview

    main

    Cesium for Unity uses native code that must be compiled for each target platform. The following platforms are supported:

    • Windows: Supports x86-64 (ARM64 is not supported) for both Editor and Player.
    • macOS: Supports Intel x86-64 and Apple Silicon (M1, M2, etc.) on macOS 10.15+ for both Editor and Player.
    • Android / Meta Quest: Supports Intel x86-64 and ARM64 (ARMv7 is not supported) for Player.
    • iOS: Supports iOS as a Player platform.
    • Universal Windows Platform (UWP): Supports Intel 64-bit and ARM 64-bit (32-bit is not supported) for Player.
    • Web: Supports WebGL and WebGPU (requires Unity 6+) for Player.
  2. Build Cesium for Unity for unsupported platforms from source

    main

    The released Cesium for Unity packages only include pre-built binaries for specific platforms. To target a new platform, you must build from the source code on GitHub.

    Implementation Steps

    1. Ensure you can build for the Unity Editor on your development machine.
    2. Add the new platform to the SupportedPlatforms list in Build~/Package.cs.
    3. Update the Run method in Build~/Package.cs to launch Unity and build for the new platform.
    4. Add a new function for your platform in Editor/BuildCesiumForUnity.cs.
    5. Modify Editor/CompileCesiumForUnityNative.cs to define how to compile the native code for your platform.
    6. Update the two ConfigureReinterop.cs files by adding a new #if-protected CppOutputPath using the correct UNITY_* symbols for your platform.

    Build Command

    Once implemented, you can build the package via the command line: dotnet run --project Build~ package --platform <MyNewPlatform>

    dotnet run --project Build~ package --platform MyNewPlatform
  3. Temporarily disable the Reinterop code generator

    main

    If you need to modify the generated code manually to experiment, follow these steps:

    1. Locate the generated code. It is typically in obj\Debug\netstandard2.1\generated\Reinterop\... or similar.

      • Tip: If you can't find it, add <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> and <CompilerGeneratedFilesOutputPath>PATH</CompilerGeneratedFilesOutputPath> to your .csproj.
      • Unity Tip: Add -generatedfilesout:"PATH" to your csc.rsp.
    2. Disable the generator. Comment out the Reinterop ProjectReference or Analyzer entry in your .csproj.

    3. Prevent compilation errors. Since the generator is no longer running, the code it usually provides is missing. Copy the files you located in step 1 into a folder named generated in your project's top-level directory.

    4. Revert. To return to automatic generation, delete the generated folder and uncomment the lines in your .csproj.

  4. Configure Web (WebGL/WebGPU) Player Settings

    main

    Cesium for Unity supports WebGL and WebGPU for Web platforms, but requires Unity 6 or later.

    Required Settings

    1. Enable Native C/C++ Multithreading: You must turn this on in the Player Settings. Failure to do so will result in wasm-ld undefined symbol errors during build time (e.g., __wasm_lpad_context or _Unwind_CallPersonality).
    2. Decompression Fallback: If you cannot configure your web server to serve .br files with the Content-Encoding: br header, enable Decompression Fallback in Player Settings to avoid errors, though this will increase startup time.

    Required HTTP Response Headers

    When hosting your build on a custom web server, you must ensure the following headers are set to support multithreading:

    • Cross-Origin-Opener-Policy: same-origin
    • Cross-Origin-Embedder-Policy: require-corp
    • Cross-Origin-Resource-Policy: cross-origin
    • Content-Encoding: br (specifically for .br files)
  5. Build and publish Reinterop

    main

    Reinterop is a Roslyn source generator that creates the C# <-> C++ interop layer. You must build and publish it to the plugin directory before Unity can compile the C# code correctly.

    Run this from the Packages/com.cesium.unity directory:

    dotnet publish Reinterop~ -o .

    Important: Do not open Unity before running this command. If you do, Unity may delete Reinterop.dll.meta because the DLL doesn't exist yet. If this happens, fix it by running:

    git restore Reinterop.dll.meta
    dotnet publish Reinterop~ -o .
  6. Implement backward compatibility for components

    main

    To implement backward compatible loading for a component (e.g., upgrading from v0.2.0), follow this pattern:

    1. Create a compatibility class: Create a new file (e.g., MyComponentBackwardCompatibility0dot2dot0.cs) that derives from the original class and implements IBackwardCompatibilityComponent<MyComponent>.
    2. Apply attributes: Use [ExecuteInEditMode], [AddComponentMenu("")], and [DefaultExecutionOrder(-1000000)] to ensure the compatibility component runs early and is hidden from the 'Add Component' menu.
    3. Map old fields: Define the old properties by appending the version to the name and using the [FormerlySerializedAs] attribute to map them to the new names.
    4. Handle Enums: If an enum was changed or removed, declare the old enum type nested inside the compatibility class.
    5. Implement Upgrade logic: Implement the Upgrade method from IBackwardCompatibilityComponent to map the old values to the new component instance.
    6. Create an Editor interface: (Optional) Create a nested Editor class with an 'Upgrade' button using CesiumBackwardCompatibility<T>.Upgrade(target).
    7. Automate via OnEnable: Call CesiumBackwardCompatibility<T>.Upgrade(this) in OnEnable to automatically upgrade components when the scene loads.
    8. Rename the Meta file: Rename the original .meta file to match the new compatibility class name so Unity treats old instances as the compatibility component.
    [ExecuteInEditMode]
    [AddComponentMenu("")]
    [DefaultExecutionOrder(-1000000)]
    internal class CesiumGlobeAnchorBackwardCompatibility0dot2dot0 : CesiumGlobeAnchor, IBackwardCompatibilityComponent<CesiumGlobeAnchor>
    {
        [FormerlySerializedAs("_adjustOrientationForGlobeWhenMoving")]
        public bool _adjustOrientationForGlobeWhenMoving0dot2dot0 = false;
    
        // ... other fields ...
    
        public string VersionToBeUpgraded => "v0.2.0";
    
        public void Upgrade(GameObject gameObject, CesiumGlobeAnchor upgraded)
        {
            // Logic to map old fields to the 'upgraded' instance
            upgraded.adjustOrientationForGlobeWhenMoving = this._adjustOrientationForGlobeWhenMoving0dot2dot0;
        }
    }
  7. Manage MonoBehaviour lifecycle and initialization

    main

    Follow these patterns to ensure reliable initialization and state management in Cesium for Unity:

    • Use OnEnable for initialization: Avoid Awake and Start because they are not invoked during domain reloads (e.g., when editing a script). OnEnable is invoked during domain reloads, allowing you to treat a reload like a scene reload.
    • Handle dependency order: OnEnable calls for different components may occur in arbitrary order. If your component depends on another (e.g., CesiumGeoreference), manually call that component's Initialize() method at the start of your own OnEnable.
    • Implement ICesiumRestartable: Implement the Restart method to allow the UI to recreate the object's state from serialized fields when Unity updates them in unspecified ways.
    • Implement Reset: Use Reset to synchronize state when Unity writes directly to serialized fields; typically, Reset should simply call Restart.
    • Restart vs Initialize:
      • Restart: Completely recreates the object's state from serialized fields, assuming the current state is invalid.
      • Initialize: Prepares the object for first use but does nothing if it is already initialized.
    • Cleanup in OnDisable: Use OnDisable for cleanup. To avoid leaks if initialization happened outside of OnEnable (like in Reset or Restart), ensure your cleanup logic checks if the component isActiveAndEnabled before proceeding.
  8. Monitor native builds during Unity game builds

    main

    When building a standalone game, Unity invokes CMake to build native code for the target platform. You can monitor the progress by viewing the build log.

    Windows (PowerShell):

    cd cesium-unity-samples/Packages/com.cesium.unity
    Get-Content -Path native~/build-Standalone/build.log -Wait

    Linux/macOS:

    cd cesium-unity-samples/Packages/com.cesium.unity
    tail -f native~/build-Standalone/build.log

    Note: Replace build-Standalone with the specific log file name shown in the Unity progress window. If CMake is not found, ensure it is in your PATH or update the path in CompileCesiumForUnity.cs.

    Get-Content -Path native~/build-Standalone/build.log -Wait
  9. Run Cesium for Unity tests

    main

    In the Unity Editor

    1. Go to Window -> General -> Test Runner.
    2. Switch to the Play Mode tab.
    3. Click Run All.

    From Package Manager installation

    If the plugin is installed via the Package Manager, tests are hidden by default. To enable them, add the following to your project's Packages/manifest.json:

    "testables": ["com.cesium.unity"]
    "testables": ["com.cesium.unity"]