This package integrates DragonECS with the Unity editor and runtime. It provides visual debugging and profiling tools, editor templates for entity/component setup, and utilities for binding entities to Unity GameObjects.
> While the English version of the README is incomplete, the [Russian README](https://github.com/DCFApixels/DragonECS-Unity/blob/main/README-RU.md) contains additional details.
Installation as a Unity package is supported by adding the Git URL [in PackageManager](https://docs.unity3d.com/2023.2/Documentation/Manual/upm-ui-giturl.html):
The package sources can be copied directly into the project.
</br>
# Debug
## Debug service
`UnityDebugService` implementation of the [Debug service for `EcsDebug`](https://github.com/DCFApixels/DragonECS/blob/main/README.md#ecsdebug). In the editor it initializes automatically and integrates with Unity systems: `EcsDebug.Print` is forwarded to the Unity console, `EcsProfilerMarker` is connected to the Unity profiler, and related debug functionality is exposed.
```c#
// Activate manually
UnityDebugService.Activate();
// Print to Unity console
EcsDebug.Print("Example message");
var someMarker = new EcsProfilerMarker("SomeMarker");
someMarker.Begin();
// Measured time will be visible in the Unity profiler.
someMarker.End();
// Stop play mode
EcsDebug.Break();
```
## Visual debugging
Visual debugging is provided as editor monitor objects that display internal framework state during `Play Mode`. Monitors are placed in the `DontDestroyOnLoad` section.
```c#
_pipeline = EcsPipeline.New()
//...
// Debugging initialization for the pipeline and worlds.
Displays processes and systems in a matrix layout. Systems are shown in execution order. A mark at the intersection of a system and a process indicates that the system is part of that process.
Displays entity state and allows adding, modifying or removing components at runtime (Play Mode). One monitor is created per entity; entity monitors are grouped under the corresponding world monitor.
To expose a component in the `Add Component` menu, a template is required. Component templates are types implementing `IComponentTemplate` or components implementing `ITemplateNode` together with `IEcsComponentMember`.
### Implementation
* Simple example:
```c#
// Add [Serializable] attribute to the component type.
class SomeComponentTemplate : ComponentTemplate<SomeComponent> { }
```
```c#
// Same for tag components.
[Serializable]
struct SomeTagComponent : IEcsTagComponent { }
class SomeTagComponentTemplate : TagComponentTemplate<SomeTagComponent> { }
```
<details>
<summary>Other approaches</summary>
#### Implementing `ITemplateNode` on a component
This approach can be convenient because it does not require a separate template class; the component itself acts as the template and is straightforward to implement. The downside is higher risk of missing references when types are renamed if `[SerializeReference]` is used.
```c#
public struct Health : IEcsComponent, ITemplateNode
{
public float Points;
public void Apply(short worldID, int entityID)
{
EcsPool<Health>.Apply(worldID, entityID) = this;
}
}
```
#### Custom template implementation
If built-in `ComponentTemplate<T>` or `TagComponentTemplate<T>` do not fit the requirements, implement a custom template by implementing `IComponentTemplate`. This can be useful for custom pools. In most cases the built-in templates are sufficient.
public void SetRaw(object raw) { component = (SomeComponent)raw; }
public void OnGizmos(Transform transform, IComponentTemplate.GizmosMode mode) { /*...*/ }
public void OnValidate(UnityEngine.Object obj) { /*...*/ }
}
```
</details>
</br>
### Customizing type display
The `Add Component` dropdown supports hierarchical grouping based on the `[MetaGroup]` attribute.
By default components in the Inspector receive a deterministic color derived from the component name. The display mode can be changed in the settings window. A specific color can be set using the `[MetaColor]` attribute.
If the integration locates the corresponding script (by matching the type name to a file or via `[MetaID]`), a file icon appears next to the remove button — single-click selects the script in the project, double-click opens it.
If `[MetaDescription]` is present, a tooltip icon is shown with the description text.
</br>
### Using component templates outside standard entity templates
Component templates can be used outside of `MonoEntityTemplate` and `ScriptableEntityTemplate` in arbitrary classes. Two approaches are provided:
Attribute `[ComponentTemplateField]`:
```c#
// Display a field as a component, customizable with meta attributes.
// Similar to components in MonoEntityTemplate or ScriptableEntityTemplate.
[SerializeField, ComponentTemplateField]
private SomeComponent _someComponent1;
```
```c#
// For SerializeReference adds a button to pick available ITemplateNode implementation
[SerializeReference, ComponentTemplateField]
private ITemplateNode _someComponent1;
```
Wrapper `ComponentTemplateProperty`:
```c#
// Wrapper around ITemplateNode, similar to the ComponentTemplateField example.
Entities and GameObjects are linked using connects. From the GameObject side use `EcsEntityConnect`; from the entity side `GameObjectConnect` is created/removed automatically. `EcsEntityConnect` acts as the manager connect.
```c#
EcsEntityConnect connect = /*...*/;
entlong entity = _world.NewEntityLong();
// Connect entity with GameObject.
// GameObjectConnect is added to the entity automatically
// and templates are applied.
connect.ConnectWith(entity);
// Or create without applying templates.
connect.ConnectWith(entity, false);
// Disconnect.
// GameObjectConnect will be removed automatically.
> To view all components of the linked entity, expand `RUNTIME COMPONENTS`.
> The bottom panel contains utility buttons: 1) Disconnect entity. 2) Delete entity. 3) Auto-fill template array. 4) Cascade auto-fill for all child connects in the hierarchy.
---
`AutoEntityCreator` automatically creates an entity and binds it to the GameObject. In the inspector specify the `EcsEntityConnect` to use and the [world provider](#world-provider) where the entity should be created.
> The bottom panel includes helper buttons: 1) Auto-fill the connect reference. 2) Cascade auto-fill for all child instances in the hierarchy.
</br>
# World Provider
`EcsWorldProvider<TWorld>` is a `ScriptableObject` wrapper over `TWorld` intended to expose a world instance via the Unity inspector. For simple scenarios the singleton provider `EcsDefaultWorldSingletonProvider` is sufficient.
```c#
// The singleton provider is created automatically under "Assets/Resource".
Lightweight Ecs root implementation for Unity. Builds a pipeline from pipeline templates. Derives from `MonoBehaviour`. Add via `Add Component > DragonECS > EcsRootUnity`.
A documentation window based on meta-attributes is available via `Tools > DragonECS > Documentation`. Documentation is generated on first open and when the `Update` button is pressed.
The settings window exposes several options, including component display modes in the Inspector. At the bottom, toggles for framework define symbols are available. Open via `Tools > DragonECS > Settings`.
Some parts of the integration heavily use `[SerializeReference]`, which can lose type information after renames. The `Reference Repairer` tool collects assets with missing types and provides an interface to map new type names and repair collected assets. Open via `Tools > DragonECS > Reference Repairer`.
> If missing types have a `[MetaID(id)]` attribute, the tool attempts automatic mapping.
## Cannot add `EcsEntityConnect` or other components
This issue may appear after a package update. Recommended remediation steps: run `Assets -> Reimport All`, or close Unity, remove the project's `Library` folder and reopen the project.