unity-game-engineunity-dotsunity-ecs

Entity not rendering after moving using EntityCommandBuffer in Unity DOTS


I am new to Unity DOTS and for a starter project, I want to move some ship entities given the speed and direction. This is my system:

namespace Obscure.SpaceShooter
{
    [BurstCompile]
    public partial struct ShipMovementSystem : ISystem
    {
        [BurstCompile]
        public void OnUpdate(ref SystemState state)
        {
            Debug.Log("OnUpdate");

            float deltaTime = SystemAPI.Time.DeltaTime;
            var ecbSingleton = SystemAPI.GetSingleton<BeginSimulationEntityCommandBufferSystem.Singleton>();

            new ShipMovementJob{
                deltaTime = deltaTime,
                entityCommandBuffer = ecbSingleton.CreateCommandBuffer(state.WorldUnmanaged)
            }.Schedule(); // same issue with Run()
        }
    }

    [BurstCompile]
    public partial struct ShipMovementJob : IJobEntity
    {
        public float deltaTime;
        public EntityCommandBuffer entityCommandBuffer;

        [BurstCompile]
        public void Execute(ShipAspect shipAspect)
        {
            float2 moveVector = shipAspect.movement.ValueRO.direction * shipAspect.movement.ValueRO.speed;
            float3 newPosition = shipAspect.transform.ValueRO.Position + new float3(moveVector.x, moveVector.y, 0) * deltaTime;

            Debug.Log($"Moving ship {shipAspect.entity.Index} to {newPosition} from {shipAspect.transform.ValueRO.Position}");

            entityCommandBuffer.SetComponent(shipAspect.entity, new LocalTransform
            {
                Position = newPosition
            });
        }
    }
}

In the scene the ship doesn't move, but in the entity inspector, their position changes. I used Debug.Log and the values match:

Console

Scene View


Solution

  • Okay so I ended up not using the EntityCommandBuffer and it works now.

    For anyone in the future, this is the final script, I also added input, and rotation with the help of a tutorial:

        [BurstCompile]
        public partial struct ShipMovementSystem : ISystem
        {
            [BurstCompile]
            public void OnUpdate(ref SystemState state)
            {
                float deltaTime = SystemAPI.Time.DeltaTime;
    
                new ShipMovementJob
                {
                    deltaTime = deltaTime,
                }.Schedule();
            }
        }
    
        [BurstCompile]
        public partial struct ShipMovementJob : IJobEntity
        {
            public float deltaTime;
    
            [BurstCompile]
            public void Execute(ShipAspect shipAspect)
            {
                // Move the ship
                float2 moveVector = float2.zero;
                if (shipAspect.movement.ValueRO.isPlayer)
                {
                    moveVector = shipAspect.inputsData.ValueRO.move * shipAspect.movement.ValueRO.speed;
                }
                float3 newPosition = shipAspect.transform.ValueRO.Position + new float3(moveVector.x, moveVector.y, 0) * deltaTime;
    
                shipAspect.transform.ValueRW.Position = newPosition;
    
                // Rotate the ship to face the direction of movement
                float rotationTime = shipAspect.movement.ValueRO.rotationTime;
                if (math.lengthsq(moveVector) > 0.01f)
                {
                    float angle = math.atan2(-moveVector.x, moveVector.y);
                    quaternion newRotation = quaternion.RotateZ(angle);
                    // smooth rotation
                    shipAspect.transform.ValueRW.Rotation = math.slerp(shipAspect.transform.ValueRO.Rotation, newRotation, rotationTime * deltaTime);
                }
                else
                {
                    // smooth rotation
                    shipAspect.transform.ValueRW.Rotation = math.slerp(shipAspect.transform.ValueRO.Rotation, quaternion.identity, rotationTime * deltaTime);
                }
            }
        }