LocalToWorld system not running after Entity created

I’m trying to change my player’s position locally in a system using math.transform(localToWorld.Value, newLocalPosition) but it seems the LocalToWorld system only runs after the first update for my player entity, so when I set the initial position to say (0, 0, -10) it goes to (0, 0, 0).
If I manually run the LocalToWorld system after creating the player entity with World.DefaultGameObjectInjectionWorld.GetOrCreateSystem<TRSToLocalToWorldSystem>().Update(); it works as expected.

I would advise you to not write directly to LocalToWorld components, instead fetch and update the Translation, Rotation and Scale/NonUniformScale/CompositeScale components in your system.
The updated values of these TRS components are used to build LocalToWorld in TRSToLocalToWorldSystem, every time this system runs.

These 2 snippets from TransformSystem docs clarify your doubt:

If any combination of Translation (float3), Rotation (quaternion), or Scale (float) components are present along with a LocalToWorld component, a transform system will combine those components and write to LocalToWorld.

User code may write directly to LocalToWorld to define the transform for an instance, if no other transform components are associated with the same entity.
1 Like

I’ll clarify that I am not writing to the LocalToWorld component but am using it as a matrix to update my player position locally instead of globally

Hey @Chixel , post your System/Entities.ForEach code which is leading to issues, so that we can help you.

probably need to add AddComponent<Unity.Transforms.CopyTransformFromGameObject>(entity)

This is all using pure ecs, no gameobject conversion

Do you have the translation and world components added ?

User code may write directly to LocalToWorld to define the transform for an instance, if no other transform components are associated with the same entity.

From https://docs.unity3d.com/Packages/com.unity.entities@0.17/manual/transform_system.html

So it is ok to write directly to LTW. But i know, there is some mess with systems order, so it could be more safe to write to TRS components.

Your quote says, if no other transform components are associated with the same entity
So if you have any translation/rotation/scale components then you can not write to LTW because Unity will override it.

If you do not have these components then of course it’s totally fine to write to LTW because Unity considers this Entity static.

how else would I move the entity? of course I do

Since this doesn’t seem to be helping much,
I have an entity with Translation, Rotation, and LocalToWorld components.
In a system I move the entity with translation = math.transform(localToWorld.Value, newLocalPosition).
But for whatever reason the first time the system gets run after the entity is created it doesn’t have the corrent localToWorld matrix values. So instead my entity gets moved to 0,0,0 the frame it’s created

How are you creating the Entity? If it’s conversion it should automatically setup the LTW.
If you’re creating the Entity from code you need to do this yourself because LTW won’t be set till translation system group updates and that’s near end of frame.

1 Like

I thought that might be the case, I’ve been updating it for the first frame with

GetExistingSystem<TRSToLocalToWorldSystem>().Update()``` but I wasn't sure if that was intended or not

Whenever we have to write this code, we should first re-think about our

  1. Manual System update ordering (where your systems are running wrt Unity systems), and
  2. Job scheduling (I mean Component dependencies through jobs)
    We should try to get rid of these kind of update calls to other systems from another system, as much as possible. In my opinion, this code is kinda an anti-pattern.

In your case, as @tertle mentioned, the translation component data will lead to an updated LTW component only when TRSToLocalToWorldSystem runs later in the frame.

User code may write directly to LocalToWorld to define the transform for an instance, if no other transform components are associated with the same entity.```

I clubbed them together for a reason. :p :)