using Unity.Burst; using Unity.Entities; using Unity.Mathematics; using Unity.NetCode; using Unity.Transforms; namespace ProjectM.Simulation { /// /// Canonical predicted system: advances each player's planar (XZ) position from twin-stick Move /// input. Runs inside the prediction loop on the owning client (re-simulated on rollback) and /// once per tick on the server; filtered to so only predicted ghosts move. /// Deterministic by construction: uses SystemAPI.Time.DeltaTime (the fixed tick step) /// only — no wall-clock, no System.Random. Move is clamped to unit length so diagonal /// keyboard movement is not faster than cardinal. Move speed is the data-driven /// (authored base + active modifiers), recomputed /// each tick by which runs before this system. /// [UpdateInGroup(typeof(PredictedSimulationSystemGroup))] [BurstCompile] public partial struct PlayerMoveSystem : ISystem { [BurstCompile] public void OnUpdate(ref SystemState state) { float dt = SystemAPI.Time.DeltaTime; foreach (var (transform, input, stats) in SystemAPI.Query, RefRO, RefRO>() .WithAll()) { float2 move = input.ValueRO.Move; if (math.lengthsq(move) > 1f) move = math.normalize(move); float3 delta = new float3(move.x, 0f, move.y) * stats.ValueRO.MoveSpeed * dt; transform.ValueRW.Position += delta; } } } }