Skip to content

Unity Editor

DigitalHeaven.Unity.Editor is a Unity Editor plugin that imports compiled .pallet files into native Unity assets — materials, textures, meshes, and prefabs. It provides an editor window for building and watching pallets, a PalletSource asset for configuring imports, and an extensibility system for game-specific pipeline hooks.

Ships alongside DigitalHeaven.Unity as pre-compiled DLLs. No source compilation required.

Open via Window → DigitalHeaven in the Unity menu bar.

ControlDescription
BuildRuns dh build then imports all pallets
Import OnlyImports existing compiled pallets without rebuilding
Start/Stop WatchingToggles auto-rebuild on source file changes

The window shows a thin progress bar at the top during builds, a status light (green when watching, gray when idle), and the last build’s result (time, asset count, errors, warnings). Below the controls is a list of all PalletSource assets in the project with buttons to select each one.

A PalletSource is a ScriptableObject that tells the import pipeline which pallet to import and where to put the results.

Create one via Assets → Create → DigitalHeaven → Pallet Source.

FieldDescription
Path ModeRelative (output relative to this asset’s folder) or Absolute (subfolder under Assets/)
PathSubfolder appended to the base path. Leave empty for the base path itself
Append Pallet NameAdd the pallet ID as a subdirectory (default: on for Absolute mode)
Pallet IDWhich compiled pallet to import
Available PalletsDropdown populated from .pallet files in the workspace build directory, with a refresh button
Output PathRead-only preview of the resolved output directory
DependenciesOther PalletSource assets this pallet depends on (for cross-pallet references)

The dependencies section validates entries against the compiled pallet’s manifest. Matched dependencies show a green “OK” indicator; entries not in the manifest show a warning. Missing manifest dependencies are flagged at the bottom of the section.

The inspector also has Build and Import Only buttons scoped to that specific pallet, and an Open DigitalHeaven Window shortcut.

Each PalletSource auto-creates a companion PalletHashStore asset (a sibling .hash.asset file). This maps CRC32 checksums and pallet paths to Unity asset references, enabling two-stage asset tracking: path match first, then hash match. Assets are moved and updated in-place when possible, preserving Unity GUIDs across rebuilds so scene references don’t break.

The inspector shows the number of tracked assets in the hash store.

When you build or import, the pipeline runs these phases in order:

  1. Textures — write texture files to disk (batched with AssetDatabase.StartAssetEditing)
  2. Materials — write non-inheriting material files (same batch)
  3. Refresh & apply settings — AssetDatabase.Refresh(), then set texture filter/wrap modes, turn sRGBTexture off for data textures, import a material’s normal images as normal maps, and wire up deferred material textures
  4. Inherited materials — copy base materials and apply child overrides
  5. Models — parse GLBs into Mesh assets + Prefabs
  6. Prefabs — build prefabs from .dh-obj / .dh-avatar definitions, each one’s resolved object through the same component appliers the runtime uses
  7. Inherited prefabs — create Unity Prefab Variants via PrefabUtility
  8. Extension post-processing — fire OnAfterImport hooks, then save and update the hash store

Dependencies are imported in topological order — if pallet A depends on pallet B, B is imported first.

  • DirectoryAssets/
    • Directoryyour-output-path/
      • Directoryio.example.my-avatar/ Pallet ID (if Append Pallet Name is on)
        • Directorytextures/
          • body-diffuse.png
          • body-normal.png
        • Directorymaterials/
          • skin.mat Unity materials
        • Directorymodels/
          • body.asset Mesh data
          • body.prefab Model prefab
        • avatar.prefab Final assembled avatar

The PrefabImporter reads each definition’s resolved object (every layer it inherits already merged by Core’s one resolver) and builds it with the runtime’s ObjectBuilder: the model, the part overrides (removal, parent, transform, enabled), then one applier per component type (dh.renderer, dh.skeleton, dh.springBone, dh.armatureLink, with dh.springCollider, dh.eyes and dh.reaction gathered for the avatar), and the records the object adds, each built the same way. Only where the assets come from differs: the editor reads the models and materials its import already wrote, and persists a humanoid Avatar beside the rig.

Spring chains and their colliders go through the same import as the runtime, so an endpointPosition and a chain’s collider list land on the prefab exactly as they do in a game. A prefab variant is built over its base’s prefab with only what departs from the base: a component whose resolved value equals what the base resolves it to is left as the base built it, a record the base adds is built only where it departs, and a record the variant removes is taken out. It binds only the chains it builds again, against the whole avatar’s colliders; the base’s chains keep what the base bound.

The MaterialImporter creates Unity Material assets from dh.material definitions. It maps semantic properties to the correct shader for the active rendering pipeline (Built-in, URP, HDRP) — the same mapping documented on the Unity runtime page. Platform overrides at platforms/unity/ are applied after the base material.

Game-specific Unity integrations (VRChat, ChilloutVR, etc.) can hook into the import pipeline via IEditorPipelineExtension:

HookWhen
OnBeforeImportBefore any assets are created
OnTextureCreatedAfter each texture is written
OnMaterialCreatedAfter each material is created
OnPrefabCreatedAfter each prefab is assembled (on the live scene instance, before save), with the definition and what it resolves to
OnAfterImportAfter all assets are imported
GetOverridePlatformsReturns the platforms (ID or built-in alias) whose override folders to search
ReadPlatformMetadataReads game-specific metadata from pallets

Register extensions via [InitializeOnLoad] with EditorPipelineExtensionRegistry. Extensions are sorted by Priority (lower = earlier). All methods have default no-op implementations — extensions only override what they need.

The editor DLL deploys to Assets/Plugins/DigitalHeaven/Editor/ — the Editor/ subfolder ensures Unity only loads it in the editor, not in builds.

The build system’s DeployToUnityProjects target in Directory.Build.targets automatically copies editor DLLs to the Editor subfolder. Game-specific editor extensions (like VRChat) are deployed to the same location.

The project is at DigitalHeaven.Unity.Editor/ in the repository.

Target frameworknetstandard2.1
C# version13.0 (PolySharp)
DependenciesDigitalHeaven.Core, DigitalHeaven.Unity
Unity referencesUnityEditor.CoreModule, UnityEngine.CoreModule, UnityEngine.ImageConversionModule, UnityEngine.AnimationModule, UnityEngine.IMGUIModule, UnityEngine.TextRenderingModule

Unity editor stub DLLs are sourced from External/Libs/Unity.Editor/ — a local-only, git-ignored directory populated from your Unity 6 Editor installation.