Using managed objects with ECS

ECS/DOTS has been fun for me, but I understand not all of the good stuff is currently supported, and if it is, it’s by some third party that makes it really convoluted. I know the C# job system can work with traditional Unity, but there some aspects which nearly short circuit my brain.

For example, when it comes to an object having an array I need to use in a job, NativeArray can’t be multidimensional, and doing a job one by one rather than in a batch ruins the point. For a waypoint system, I tried doing a GameManager-scope waypoint NativeArray, then in a job, grab that array, allocate another array for each NPC’s waypoint IDs (index into the waypoint array GameManager has), and allocate yet another array for the offsets of the ID array. In the end, it bore no fruit and my brain was burnt to a crisp.

So to make life easier and still utilise ECS for other things, I decided to take a performance hit for navigation after reading Reddit - Dive into anything. It seems to kind of (?) work, except I have no way of copying a NavMeshAgent from a game object to an entity. If I grab the component and add it via EntityManager.AddComponentObject, it only grabs a reference, which of course gets deleted with the parent object. My last attempt was to Object.Instantiate the NavMeshAgent component, but Unity instead clones the entire game object instead of just the component.

Given the above, I’m out of ideas. I want to use ECS and am willing to take a performance hit for navigation until ECS gets an official nav mesh system of its own. However, I feel forced to choose traditional or ECS in their entirety.

You can have similar behavior to a mult-multidimensional array by having a longer array. Each row or column will be easy to calculate if you know row or column length.

A quick search turned up this webpage.

https://eli.thegreenplace.net/2015/memory-layout-of-multi-dimensional-arrays

offset = irow * NCOLS + icol

1 Like

For attaching monobehaviours to entities you should use hybrid components. DOTS Hybrid Components | Entities | 0.17.0-preview.42

2 Likes

Appreciate the tips, guys. I looked over the docs you mentioned and tried to implement a GOCS-derived class, but my entity just sits there with no components shown in the entity debugger inspector.

For context, AIMovement is an IComponentData with some waypoint data in it. I decided to use it as a filter seeing as all AI movement will use nav meshes.


/// <summary>
/// Because Unity ECS lacks a nav mesh system, use the classic one with our entities for now.
/// </summary>
public class NavMeshAgentTransferSystem : GameObjectConversionSystem
{
protected override void OnUpdate()
{
Entities.WithAll<AIMovement>().ForEach((NavMeshAgent agent) =>
{
AddHybridComponent(agent);
});
}
}```

There’s an ECS one, if you need one:
https://discussions.unity.com/t/829507

For this to work as written you’d have to ensure the AIMovement component was added by some other conversion method before this system runs.

I did, via IConvertGameObjectToEntity. I’m guessing an UpdateAfter attribute might work?

if you are good with unsafe code and pointers, you can use a native array of an unsafe struct which holds your data pointer, count, allocator ect… you can easly manage it using unsafeUtity and NativeArrayUnsafeUtility.
i use this approach in extreme cases where i need to Create /Pass an unknow amount of native arrays within / to a job.

I’d rather not. I mean I use pointers and stuff in C++ but in C# it seems like an ugly mess. I also gave DotNav a try and it seems very limited right now. I remember an ECS sample where an Animation object was made a blob asset, but it required a new struct and stuff and there’s no explanation how it works.