GLTF Loading Guide
Learn how to import external 3D models at runtime using S1MAPI's GLTF loader.
Overview
S1MAPI includes a native GLTF/GLB loader with no external dependencies. It handles:
- GLB (binary GLTF) files
- JSON-based GLTF files
- External resources ( textures, buffers)
- Coordinate system conversion (GLTF right-handed → Unity left-handed)
- Material creation and texture mapping
Loading GLB Files
From Bytes
using S1MAPI.Gltf;
// Load GLB data from file or embedded resource
byte[] glbData = File.ReadAllBytes("path/to/model.glb");
// Load and return root GameObject
GameObject? model = GltfLoader.LoadGlb(glbData);
if (model != null)
{
model.transform.position = new Vector3(0, 0, 0);
model.transform.localScale = Vector3.one;
}
Using the Generic Load Method
// Load from bytes (auto-detects format)
GameObject? model = GltfLoader.Load(glbData);
// With custom shader
Shader customShader = Shader.Find("Universal Render Pipeline/Lit");
GameObject? model = GltfLoader.Load(glbData, shader: customShader);
From File
// Load directly from file path
GameObject? model = GltfLoader.LoadFromFile("path/to/model.glb");
// With custom shader
GameObject? model = GltfLoader.LoadFromFile("path/to/model.glb", myShader);
Loading GLTF JSON
GLTF JSON files can reference external binary buffers and textures:
string gltfJson = File.ReadAllText("path/to/model.gltf");
string basePath = "path/to/"; // Directory containing external resources
GameObject? model = GltfLoader.LoadFromJson(gltfJson, basePath);
Using GltfImporter Directly
For more control over the import process:
using S1MAPI.Gltf;
GameObject? model = new GltfImporter()
.SetShader(myShader) // Custom shader for materials
.SetEmissionIntensity(2.0f) // Emission multiplier
.Load(glbData); // Load the model
GltfImporter Options:
| Method | Description |
|---|---|
SetShader(Shader shader) |
Use custom shader for materials |
SetEmissionIntensity(float intensity) |
Set emission color intensity multiplier |
Load(byte[] data) |
Load GLB or GLTF bytes |
LoadGlb(byte[] glbBytes) |
Load GLB specifically |
LoadGltfJson(string json, string basePath) |
Load GLTF JSON with base path |
LoadFromFile(string path) |
Load from file path |
Loading Embedded Resources
Load GLB files embedded in your mod assembly:
using S1MAPI.Utils;
using S1MAPI.Gltf;
// Load from embedded resource (assembly must contain the file)
byte[]? glbData = EmbeddedResourceLoader.LoadBytes("MyMod.Resources.sign.glb");
if (glbData != null)
{
GameObject? sign = GltfLoader.LoadGlb(glbData);
if (sign != null)
{
sign.transform.SetParent(building.transform);
sign.transform.localPosition = new Vector3(12f, 2.4f, 4.85f);
sign.transform.localRotation = Quaternion.Euler(0f, 180f, 0f);
sign.transform.localScale = Vector3.one * 0.3f;
}
}
Material Handling
Default Material Behavior
- Materials are created using S1MAPI's default shader (URP Lit → Standard → Hidden/Internal-Colored)
- Textures are applied if found in the GLTF file
- Emission is supported with configurable intensity
Custom Shader
Shader urpShader = Shader.Find("Universal Render Pipeline/Lit");
GameObject? model = new GltfImporter()
.SetShader(urpShader)
.Load(glbData);
Coordinate System
GLTF uses a right-handed coordinate system, while Unity uses left-handed. S1MAPI automatically handles the conversion by:
- Inverting the Z axis
- Converting the rotation matrix
- Properly orienting the mesh data
This means models appear correctly oriented without manual transformation.
Example: Neon Sign
using S1MAPI.Utils;
using S1MAPI.Gltf;
using UnityEngine;
public static class SignLoader
{
public static GameObject LoadNeonSign(GameObject parentBuilding)
{
// Load embedded GLB
byte[]? glbData = EmbeddedResourceLoader.LoadBytes("MyMod.Resources.neon_open_sign.glb");
if (glbData == null)
{
Debug.LogWarning("Failed to load neon sign");
return null;
}
// Import with emission
GameObject? sign = new GltfImporter()
.SetEmissionIntensity(4.0f) // Boost emission for neon effect
.Load(glbData);
if (sign == null)
{
Debug.LogWarning("Failed to import neon sign");
return null;
}
// Configure transform
sign.name = "NeonOpenSign";
sign.transform.SetParent(parentBuilding.transform);
sign.transform.localPosition = new Vector3(12f, 2.4f, 4.85f);
sign.transform.localRotation = Quaternion.Euler(0f, 180f, 0f);
sign.transform.localScale = Vector3.one * 0.3f;
return sign;
}
}
Performance Considerations
Cache loaded models: If you load the same GLB multiple times, cache the result.
Use appropriate scale: GLTF models often use different scale conventions. Adjust
localScaleas needed.Emission intensity: Higher values create brighter glow effects but check visual quality.
Resource cleanup: GLTF imports create meshes, materials, and textures. Unity handles cleanup automatically when GameObjects are destroyed.
Troubleshooting
Model Appears Black
- Check if the shader is supported (URP Lit recommended)
- Verify textures are being loaded correctly
Model Orientation is Wrong
- S1MAPI should handle conversion automatically
- If still wrong, try flipping the Z scale:
model.transform.localScale = new Vector3(1, 1, -1)
Model is Too Large/Small
- Adjust
localScaleto match your scene - Common GLTF scale factors: 0.01, 0.1, 1.0, 100 (depends on source)
Missing Textures (GLTF JSON)
- Ensure
basePathpoints to the correct directory - Check that texture files exist and are readable
Supported GLTF Features
- Meshes: Positions, normals, UVs, tangents, colors
- Materials: PBR metallic-roughness, unlit, emission
- Textures: PNG, JPEG formats
- Nodes: Hierarchy and transforms
- Animations: Not currently supported (contact if needed)
Next Steps
- Building Guide - Add GLTF models to buildings
- Examples - Complete examples with GLTF
- API Reference - Full API docs