Copy Translation and Rotation to GameObject.transform

Hi

I have a bit of code that takes an enity position and rotation and updates a GameObject

Rotation rotationData = EntityManagerRef.GetComponentData(ECSEntity);
Translation translationData = EntityManagerRef.GetComponentData(ECSEntity);

transform.position = translationData.Value;
transform.rotation = rotationData.Value;

This works fine however when there are too many objects this becomes very slow… Is there a better way at the moment to do something like this? some automatic system in ecs or something i can develop

Thanks!

1 Like

The magic API here is TransformAccessArray. There are a couple of built-in mechanisms that use this such as CopyTransformToGameObjectSystem and CompanionGameObjectUpdateTransformSystem. Note that TransformAccessArray is actually a list with a fixed capacity. You’ll need to use it as such if you want to keep GC down.

Is there anything similar for other (custom) IComponentData?

TransformAccessArray is specific to modifying GameObject Transform components in jobs with Burst. I’m not sure what you are asking nor what you are trying to do.

and if i wanted to fill an array of Matrix4x4 for use with the instance api, any idea how would i go with this?

Example: Grab the translation and rotation from 1000 entities and construct a Matrix4x4 for each, is this something i can do as a job or some other way?

You could just let the TransformSystemGroup run before this, and then copy out the LocalToWorld matrices to your custom arrays. Or if you are using DramMeshInstancedIndirect, you can use an IJobChunk.ExecuteWithoutJobs and ComputeBuffer.SetData using the 4 argument overload.

Edit: If you don’t want to use TransformSystemGroup, you can construct a float4x4 from the rotation and translation using the float4x4(quaternion, float3) constructor. float4x4 is byte-per-byte equivalent to Matrix4x4 so you can reinterpret a NativeArray if necessary, or there’s an implicit conversion operation defined between the two.

2 Likes

TransformArrayAccess does as far as I understood it support to copy Arrays of Transform, Rotate, Scale Components out of Dots into the MonoBehaviours (MainThread). The question was if there is anything that allows to copy out arrays of custom defined “MyComponent : IComponentData” out to the MainThread. The only API I’ve found was EntityManager.GetComponentData - which only supports to copy one component for a specific entity out - which is also what argibaltzi ran into.

TransformAccessArray doesn’t do anything with Translation, Rotation, and Scale components. It lets you write into the GameObject Transform from a Burst job. There are no other data types that let you write into the other built-in GameObject components’ properties. However, if you have fields in your MonoBehaviours and are willing to go unsafe you could maintain a NativeArray of pointers into those fields and copy from a Burst job that way.

1 Like

I am trying to figure out how to copy the LocalToWorld to my arrays, do you have any pointers for this? It would propably need to run on a job or so because the number of entities are too many.

I have this:
public NativeArray ECSEntity;
How do i grab the LocalToWorld data from each entity fast

For the very specific case where you have to grab the LocalToWorld for each entity in ECSEntity in that order, the tool you need is ComponentDataFromEntity.

I’m still very confused as to what you are trying to do. First you were trying to sync transforms to GameObjects, which made sense to me. But now you are trying to render entities using Graphics API rather than using HybridRenderer. Why?

1 Like

i am trying both, different cases. sorry for confusion!

The hybridrenderer has some issues which i dont want to get involved with at the moment, a lot of incomplete functionality

I am still trying to figure out some parts of ECS
i want to get the localToWorld from the specific array of entities, from what i understand i would need to tag them in order to get them inside a job?

I am not sure what features DrawMeshInstancedIndirect has that HybridRenderer doesn’t other than maybe GPU texture skinning or built-in renderer support.

Nope. You just need that NativeArray and ComponentDataFromEntity and whatever you plan to write to.

No matter what i do this is just expensive… Getting access to Translation and Rotation component data is slow

A simple entites for each system for 10k entities takes forever using a look up table
Do i need to run this system before or after some other system to get better performance? i noticed many times other systems are using it like the physics

  Entities.ForEach((Entity entity, ref LinkEntityToGameobjectComponentData linker, ref Translation translation, ref Rotation rotation) =>
        {
            count++;
            References[linker.ReferenceIndex].TransformRef.position = translation.Value;
            References[linker.ReferenceIndex].TransformRef.rotation = rotation.Value;
        });

I also tried a TransformAccessArray system but its the same problem again… its waiting for some job somewhere and takes forever to take the translation and rotation data

I even tried the hybrid renderer, it was also waiting for jobs to finish before it can update translations and rotations

Define “slow” and “forever”? These are ambiguous terms.

The Timeline view in the Profiler can give you some ideas of the order systems are running, what is waiting on what, and when you have worker threads sitting idle.

Code Snippet: That looks like you are using ComponentSystem rather than SystemBase. ComponentSystem is very slow.

Are you trying to remove the sync point or do you think that waiting for jobs to finish that have to run anyways is slow?

Did the Hybrid Renderer meet your needs functionally? If so, stick to that. It really sounds like you have something else in your project that is slow and should focus on making that faster.

1 Like

thanks for your input but i am still not sure how to do this efficiently, i think i will take a break…
how hard is it to get the translation and rotation of each entity and update a gameobject jezus