Search Unity

Question Does GetCollisionWorldFromTick() includes ghosts?

Discussion in 'NetCode for ECS' started by Samsle, Mar 23, 2021.

  1. Samsle

    Samsle

    Joined:
    Mar 31, 2020
    Posts:
    110
    Hi, I know that Unity Physics is currently not supported for prediction, so I tried my luck with rayCasts which is working perfectly for static objects like walls.

    Now I wanted to achieve, that also the players can block each other.
    In the DOTSExample it seems this is not implemented. I tried with some thin clients, but I could walk through each character.

    Currently with my setup the local player is predicted, but also the other players are predicted via input-prediction (see my other thread). In case a movement-button is pressed for a long time by every player, this works perfectly! Even with high delays, the position of all the players are the same on each device.

    In this case, when every player on each client is perfectly predicted, I would expect that also the prediction of hits of each other would work correct, but this is not the case. Every time when a player hits another player, the player does not stop on prediction, but only when the rollback happens, which leads to weird snap backs (I have an own Component for velocity, which will be set to 0 in such a case, so that the translation gets not changed).

    For the rayCasts I used collisionHistory.GetCollisionWorldFromTick(predictingTick, delay.Delay, out collWorld) and alternatively physicWorld.CollisionWorld. But did not make any difference.

    I also tried to do the rayCasts (and stopping of players) only on m_predictionGroup.IsFinalPredictionTick. But this was not even working in prediction on static objects anymore.

    I read some hours/days through the character controllers in the DOTSExample, but could not find any hint how to do it, maybe someone can help me out here? Is this even possible to achieve? I had somehow the feeling that the ghosts are not in the collisionWorld, or not at the correct position? :confused:
     
    Last edited: Mar 23, 2021
  2. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    895
    Ghosts are part of the physics world and the ghost colliders positions we backup is the last simulated physics frame.
    Here is where problem starts, since without modification of the physics loop, server and client are moving and predicting objects differently.

    The physics update is execute always after the GhostSimulationGroup. That means, whatever the ghosts does inside each of the prediction tick, is not reflect on the physics until the end of the prediction update.
    On the client then, since ghost can predict "partial ticks" (ServerTickFragment < 1) if the physics does not runs inside the prediction loop and is aware of that (skip those updates) the position of the rigid body and its velocity may be simulated in a different way in respect to server.

    All of that can cause some sort of problem with the collision history.
    On the server, the data stored is always the result of full simulation update (so GhostPrediction + Physics with the frame delta time). And that is fine, even though you technically always raycast to the collider positions "in the past frame" kinda.
    On the client, the data in the history buffer can be slightly in different position for the same ServerTick in presence of partial updates. Physics is unaware that the updated position for the ghost is only partial (delta time for the prediction step < delta frame time) and it still run a full physics loop.

    Predicted object position (and data) are also restored from the last full predicted tick (GhostPredictionHistorySystem) when running the next partial prediction, but the collision world doesn't;
    So when you check the raycast again the other player, bounding volumes might be way off.

    At least that's my guess. A fact the tell me this may be the case is that:
    witch suggests that on the server the collision checks are working as expect. Am I correct ?

    I'm also assuming that:
    • since you have your own velocity, your ghosts are all Kinematic rigid body (so physics is not involved in the collision detection) and you never set the PhysicsVelocity component (it is always 0). In case you do the latter, you must be aware that DOTSPhysics, contrarily to PhysicsX, will still move the Kinematic object (so integration still take place) but collision are not handled.
    • since you mentioned collisionHistory.GetCollisionWorldFromTick, you are using the raycast inside the GhostPredictionSystemGroup and not inside the FixedStepSimulationSystemGroup.

    For ticks that aren't the final tick you can probably raycast in the collision world with collisionHistory.GetCollisionWorldFromTick() (it should have stored good data).
    But for the IsFinalPredictionTick if the ServerTickFraction < 1, you may want to try to raycast again the previous tick (PredictedTick - 1, that is the last full tick stored) instead.

    In the upcoming version of NetCode we added some support (while not perfect yet) for running physics inside the prediction loop (with the correct ticking logic). That may definitively help solving many headache.

    We also have some internal demo that use player prediction and physics (by colliding with other predicted objects and players in the scene) and collisions kinda works.
    But we/I didn't try with raycast though, so I will play around that a little with the new setup
     
    Enzi and Samsle like this.
  3. Samsle

    Samsle

    Joined:
    Mar 31, 2020
    Posts:
    110
    Thanks @CMarastoni for the detailed answer!
    I had to read it multiple times & had to visualize it for myself to understand the basic points ^^
    And even if it does not solve my problem right now, it helps to understand the underlaying problems. So big thanks for this!

    Exactly

    I tried this, but cannot tell that there is big difference, at least not visually -still snap backs on predicted player-to-player collissions.

    Actual if it would work with something else than raycasts, I would take it. So I'm really looking forward for the upcoming version of NetCode & I hope that there is maybe any chance for the internal demo to become external at some point in future :)
     
  4. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    895
    Thanks to you to prompt the problem out actually!
    It would be great if you can tell me more about how you check for those collision or provide a small sample that use the same logic of yours.
    So I will able to investigate a little more on my end
     
  5. l33t_P4j33t

    l33t_P4j33t

    Joined:
    Jul 29, 2019
    Posts:
    232
    from where did you get delay.Delay?

    Edit: you need to add delaycomponentauthoring to your ghost
     
    Last edited: Apr 14, 2021