Skip to main content
ChroMapper is a Unity application, so your plugin runs inside the Unity runtime. The template project pre-references a set of Unity modules, making their APIs available to your code at compile time without any additional setup.
Unity APIs are available in your plugin because ChroMapper runs on the Unity engine. You are not embedding Unity in your DLL — you are calling into the Unity runtime that ChroMapper already provides. The Unity DLLs are never copied to your build output; ChroMapper supplies them at runtime.

Pre-referenced Unity modules

The .csproj references the following Unity modules. All of them are resolved from $(ChroMapperDir)\ChroMapper_Data\Managed\<dll>:
AssemblyWhat it provides
UnityEngine.CoreModuleGameObject, Transform, MonoBehaviour, Debug, Time, and most core types
UnityEngine.InputLegacyModuleLegacy Input class (Input.GetKey, Input.mousePosition, etc.)
UnityEngine.UIuGUI components: Button, Toggle, Slider, Image, Text
UnityEngine.UIModuleCanvas system and UI event infrastructure
UnityEngine.UnityWebRequestModuleUnityWebRequest for HTTP calls
Unity.InputSystemNew Input System (InputAction, InputActionMap, keyboard and gamepad bindings)
Unity.TextMeshProTMP_Text, TextMeshProUGUI, and related rich-text components
UnityEngine.ImageConversionModuleImageConversion helpers for PNG/JPG encode and decode
UnityEngine.AudioModuleAudioClip, AudioSource, AudioListener
UnityEngine.TextRenderingModuleFont and legacy text rendering
ChroMapper-specific assemblies are also referenced:
AssemblyWhat it provides
MainChroMapper’s primary game logic and editor types
InputChroMapper’s input handling layer
LiteNetLibNetworking library used by ChroMapper
PluginsChroMapper’s plugin host infrastructure and the [Plugin] / [Init] attributes
0HarmonyHarmonyLib runtime, bundled with ChroMapper

How Unity DLL references are resolved

Every Unity reference in the .csproj uses a HintPath that points into the ChroMapper installation directory:
<Reference Include="UnityEngine.CoreModule">
    <HintPath>$(ChroMapperDir)\ChroMapper_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
    <Private>False</Private>
</Reference>
$(ChroMapperDir) is an environment variable you set to your ChroMapper installation path (for example C:\Program Files\ChroMapper). MSBuild reads it at build time to locate each DLL. The <Private>False</Private> flag tells MSBuild not to copy the Unity DLLs to your build output directory. ChroMapper already ships them, and duplicating them would cause version conflicts.
You must set the ChroMapperDir environment variable before building. If it is missing or points to the wrong directory, MSBuild cannot resolve the HintPath references and the build will fail. See Build and deploy.

Logging with Debug.Log

UnityEngine.Debug.Log writes to both ChroMapper’s console overlay and Unity’s log file. The template’s Init method uses it to confirm the plugin loaded:
Debug.Log($"Hello from {Name}!");
Use Debug.Log, Debug.LogWarning, and Debug.LogError throughout your plugin to trace behaviour. The Unity log file on Windows is at:
%APPDATA%\..\LocalLow\BinaryElement\ChroMapper\Player.log

Using the Input System

The template references both the legacy Input module and the new Unity.InputSystem. For new plugins, prefer the new Input System:
using UnityEngine.InputSystem;

// Check whether a key was pressed this frame
if (Keyboard.current.spaceKey.wasPressedThisFrame)
{
    Debug.Log("Space pressed");
}
For quick prototyping the legacy API is simpler:
using UnityEngine;

if (Input.GetKeyDown(KeyCode.Space))
{
    Debug.Log("Space pressed (legacy)");
}

Using uGUI and TextMeshPro

You can instantiate UI elements onto ChroMapper’s existing canvases or create your own. TextMeshPro is the recommended text component for any UI you build:
using TMPro;
using UnityEngine;
using UnityEngine.UI;

// Create a TextMeshProUGUI label on an existing canvas
var go = new GameObject("MyLabel");
go.transform.SetParent(existingCanvas.transform, false);
var label = go.AddComponent<TextMeshProUGUI>();
label.text = "Hello from MyPlugin";
label.fontSize = 14;
Prefer TextMeshProUGUI over the legacy UnityEngine.UI.Text component. ChroMapper’s own UI uses TextMeshPro, so its shader and font assets are already loaded at runtime.

Using AudioSource and AudioClip

The UnityEngine.AudioModule reference gives you access to AudioSource and AudioClip. You can load audio from a UnityWebRequest and play it through a new AudioSource attached to a GameObject in the scene.
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

IEnumerator LoadAndPlay(string path)
{
    using var request = UnityWebRequestMultimedia.GetAudioClip("file://" + path, AudioType.WAV);
    yield return request.SendWebRequest();
    var clip = DownloadHandlerAudioClip.GetContent(request);
    var source = new GameObject("AudioPlayer").AddComponent<AudioSource>();
    source.clip = clip;
    source.Play();
}

Build docs developers (and LLMs) love