A Unity plugin for importing and exporting glTF files with OMI (Open Metaverse Interoperability) extensions.
- Interface-driven architecture: Easily customize how OMI extensions map to your project's objects
- Default Unity handlers: Built-in support for converting OMI extensions to Unity components
- glTFast integration: Seamless integration with the glTFast library
- Import & Export: Full support for both importing and exporting OMI extension data
- Async operations: Non-blocking import/export operations
- Validation: Built-in validation utilities for extension data
OMI_physics_shape- Collision shapes (box, sphere, capsule, cylinder, convex, trimesh)OMI_physics_body- Rigid body physics (static, kinematic, dynamic, trigger)OMI_physics_joint- Physics constraints (fixed, hinge, slider, ball socket, 6DOF)OMI_physics_gravity- Custom gravity zones (directional, point)
OMI_spawn_point- Spawn points for players/objectsOMI_seat- Seating positions with IK dataOMI_link- Hyperlinks and navigation targets
KHR_audio_emitter- 3D audio emittersOMI_audio_ogg_vorbis- Ogg Vorbis audio codec supportOMI_audio_opus- Opus audio codec support
OMI_vehicle_body- Vehicle physics bodyOMI_vehicle_wheel- Vehicle wheelsOMI_vehicle_thruster- Directional thrustersOMI_vehicle_hover_thruster- Hovering thrusters
OMI_environment_sky- Skybox configuration (gradient, panorama, physical, plain)
OMI_personality- AI agent personality traits and prompts
- Open Unity Package Manager (Window > Package Manager)
- Click the
+button in the top-left corner - Select "Add package from git URL..."
- Enter the following URL:
https://github.com/Five-Squared-Interactive/omi-gltf-unity.git - Click "Add"
The package manager will automatically install the required dependencies (glTFast and Newtonsoft.Json).
Alternatively, you can add the package directly to your project's Packages/manifest.json:
{
"dependencies": {
"com.fivesquared.omi-gltf": "https://github.com/Five-Squared-Interactive/omi-gltf-unity.git",
...
}
}To install a specific version or branch, append # followed by the branch name, tag, or commit hash:
https://github.com/Five-Squared-Interactive/omi-gltf-unity.git#v0.1.0
https://github.com/Five-Squared-Interactive/omi-gltf-unity.git#main
https://github.com/Five-Squared-Interactive/omi-gltf-unity.git#develop
If you prefer not to use Git URL installation:
- Install glTFast via Unity Package Manager (required dependency)
- Download or clone this repository
- Copy the
RuntimeandEditorfolders to your project'sAssets/OMIdirectory
using OMI.Integration;
using UnityEngine;
public class LoadExample : MonoBehaviour
{
public string gltfUrl = "https://example.com/model.glb";
async void Start()
{
using var loader = new OMIGltfLoader();
if (await loader.LoadAsync(gltfUrl))
{
var root = await loader.InstantiateAsync(transform);
Debug.Log($"Loaded: {root.name}");
}
}
}Add an OMI > glTF Loader component to any GameObject, set the URL, and enable "Load On Start".
Implement custom handlers to control how OMI extensions are processed:
using OMI;
using OMI.Extensions.SpawnPoint;
using UnityEngine;
using System.Threading;
using System.Threading.Tasks;
public class MySpawnPointHandler : IOMINodeExtensionHandler<OMISpawnPointNode>
{
public string ExtensionName => "OMI_spawn_point";
public int Priority => 100;
public Task OnImportAsync(OMISpawnPointNode data, OMIImportContext context,
CancellationToken ct = default)
{
return Task.CompletedTask;
}
public Task<OMISpawnPointNode> OnExportAsync(OMIExportContext context,
CancellationToken ct = default)
{
return Task.FromResult<OMISpawnPointNode>(null);
}
public Task OnNodeImportAsync(OMISpawnPointNode data, int nodeIndex,
GameObject target, OMIImportContext context, CancellationToken ct = default)
{
// Your custom logic here
Debug.Log($"Custom spawn point: {data.Title} on {target.name}");
return Task.CompletedTask;
}
public Task<OMISpawnPointNode> OnNodeExportAsync(GameObject source,
OMIExportContext context, CancellationToken ct = default)
{
// Your custom export logic
return Task.FromResult<OMISpawnPointNode>(null);
}
}Register your handler:
var manager = new OMIExtensionManager();
manager.RegisterHandler<OMISpawnPointNode>(new MySpawnPointHandler());OMI/
├── Runtime/
│ ├── Core/
│ │ ├── IOMIExtensionHandler.cs # Handler interfaces
│ │ ├── OMIExtensionManager.cs # Handler registry
│ │ ├── OMIImportContext.cs # Import context
│ │ ├── OMIExportContext.cs # Export context
│ │ ├── OMIDefaultHandlers.cs # Default handler registration
│ │ ├── OMISettings.cs # Settings classes
│ │ └── OMIValidator.cs # Validation utilities
│ ├── Extensions/
│ │ ├── Audio/ # KHR_audio_emitter
│ │ ├── EnvironmentSky/ # OMI_environment_sky
│ │ ├── Link/ # OMI_link
│ │ ├── Personality/ # OMI_personality
│ │ ├── PhysicsBody/ # OMI_physics_body
│ │ ├── PhysicsGravity/ # OMI_physics_gravity
│ │ ├── PhysicsJoint/ # OMI_physics_joint
│ │ ├── PhysicsShape/ # OMI_physics_shape
│ │ ├── Seat/ # OMI_seat
│ │ ├── SpawnPoint/ # OMI_spawn_point
│ │ └── Vehicle/ # OMI_vehicle_*
│ ├── DefaultHandlers/ # Built-in Unity handlers
│ └── Integration/ # glTFast integration & export
├── Editor/
│ ├── OMISettingsEditor.cs # Settings inspector
│ ├── OMIComponentInspectors.cs # Component inspectors
│ └── OMIExportMenu.cs # Export menu items
└── Tests/
├── Editor/ # Unit tests
└── Runtime/ # Runtime tests
The plugin uses a handler pattern that allows customization at multiple levels:
┌─────────────────────────────────────────────────────────────┐
│ glTF Document │
├─────────────────────────────────────────────────────────────┤
│ OMIExtensionManager │
│ ├── Registers handlers for each extension │
│ └── Routes extension data to appropriate handler │
├─────────────────────────────────────────────────────────────┤
│ Handler Types: │
│ ├── IOMIDocumentExtensionHandler - Document-level (sky) │
│ ├── IOMINodeExtensionHandler - Per-node (spawn, seat) │
│ └── IOMIExtensionHandler - Base interface │
├─────────────────────────────────────────────────────────────┤
│ Default Handlers (Unity) Custom Handlers │
│ └── Create Unity components └── Your framework │
└─────────────────────────────────────────────────────────────┘
For frameworks that wrap Unity objects, handlers can use nodeIndex and CustomData instead of GameObject:
public class WebVerseSpawnPointHandler : IOMINodeExtensionHandler<OMISpawnPointNode>
{
public string ExtensionName => "OMI_spawn_point";
public Task OnNodeImportAsync(OMISpawnPointNode data, int nodeIndex,
GameObject target, OMIImportContext context, CancellationToken ct = default)
{
// Get our custom entity from the context
if (context.CustomData.TryGetValue($"entity_{nodeIndex}", out var entityObj))
{
var entity = entityObj as MyEntity;
entity.SetSpawnPoint(data.Team, data.Group);
}
// Don't add Unity component - we handle it ourselves
return Task.CompletedTask;
}
}The plugin includes comprehensive validation for all extension data:
using OMI;
// Validate physics shape
var shapeResult = OMIValidator.ValidatePhysicsShape(shapeData);
if (!shapeResult.IsValid)
{
foreach (var error in shapeResult.Errors)
Debug.LogError(error);
}
// Validate environment sky
var skyResult = OMIValidator.ValidateEnvironmentSky(skyData);
skyResult.LogAll(); // Logs all errors and warningsValidatePhysicsShape()- Shape dimensions, mesh indicesValidatePhysicsBody()- Mass, inertia, motion typeValidatePhysicsJoint()- Node indices, constraint limitsValidatePhysicsGravity()- Gravity values, unit distanceValidateSpawnPoint()- String lengthsValidateSeat()- Position arrays, angle rangesValidateLink()- URI formatValidateEnvironmentSky()- Colors, curves, texture indicesValidateVehicleBody()- Dampening, gyro valuesValidateVehicleWheel()- Radius, suspension settingsValidateVehicleThruster()- Force, gimbal limitsValidateAudioEmitter()- Gain, cone angles, distances
using OMI.Integration;
// Export a GameObject hierarchy to glTF
var exporter = new OMIGltfExporter();
await exporter.ExportAsync(gameObject, "output.gltf");
// Export with options
var settings = new OMIExportSettings
{
Format = OMIExportFormat.GLB,
IncludeInactive = false
};
await exporter.ExportAsync(gameObject, "output.glb", settings);Use the menu: OMI > Export Selected to glTF/GLB
Or add an OMIGltfExporterComponent to your root object and configure export settings in the inspector.
The plugin includes comprehensive unit tests:
# Run tests from Unity Test Runner
# Window > General > Test RunnerTest coverage includes:
- Data parsing for all extensions
- Default value handling
- Validation logic
- Component round-trip serialization
- Unity 2021.3 or later
- glTFast 6.0 or later
- Newtonsoft.Json (via glTFast)
MIT License - see LICENSE for details.
Contributions are welcome! Please see the OMI Group's contribution guidelines.