For some reason the client spawns the bullets “off” then they are “fixed” to where they should be. I assume this has to do with the server “correcting” what the client thought? It is exacerbated by a high velocity.
See video of the bullets being “wrong” then being updated:
If the client is predicting physics, and it is “correct” because it is not interacting with anything, why would the bullet not spawn in the correct location? When the player is not moving or moving very slowly this issue is not noticeable, it is when my player is moving quickly laterally. It is like the client is spawning the bullet where the player was? Or is it something else?
The system setup looks ok to me, so I would guess it is something in the spawning system.
When doing predicted spawning you have to take care to not run the spawn logic for rollbacks, and that is the most common issue causing problems like you describe. In our asteroids sample we use a cooldown which is not rolled back to make sure we do not spawn for the same tick multiple times - but it is an area we are working on improving and making easier
IIRC the PredictedPhysicsSystemGroup move the physics systems once in the first update whence the PredictedPhysicsConfig entity is present.
if (!m_SystemsMoved)
{
MovePhysicsSystems();
m_SystemsMoved = true;
if (physicsConfig.DisableWhenNoConnections)
{
var query = GetEntityQuery(typeof(NetworkStreamConnection));
RequireForUpdate(query);
}
}
Looks like to me the system is not running.
And because it is inside the GhostPredictionSystemGroup that only happen if there are ghost to predict.
You can check that the condition are actually met and the method is that move the system is called?
The same problem seems to exist in the Asteroids example. The position of the player when receiving input (InputSystem) and when processing input and spawning bullets (SteeringSystem) do not match. (on client)
In the example (SteeringSystem.cs), I moved the line position.Value.xy += Velocity.Value * deltaTime; below input handling if (inputData.shoot != 0 && canShoot) { ... } for correct comparison.
attached Asteriods example and one more my example screenshots.