Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question How would you manipulate server-spawned prefab physics on client in real time?

Discussion in 'Netcode for GameObjects' started by XanderCodes, Mar 22, 2024.

  1. XanderCodes

    XanderCodes

    Joined:
    Oct 14, 2015
    Posts:
    12
    The problem
    I have a game that implements netcode for gameobjects. I use network transform and network rigidbody to synchronize movement forces and knockback forces for enemies.

    My problem is that each client should be able to modify the physics forces in real time. For example, when a client shoots a projectile, the impact of the projectile should cause an AddForce() knockback effect right away. I like that when an enemy is hit the knockback makes every subsequent hit harder due to this immediate change in physics (the sudden knockback). Since the force must be applied via the owner (server) of the enemy prefab, I must use an rpc or network variable to propagate the changes to the clients. This causes delay between when a projectile hits an enemy and when it gets knocked back on the client side. Bad stuff. Not responsive. Enemies become easier to kill for clients when this happens since the movement is delayed, more projectiles can be landed before the knockback is applied.

    Just as an extra bit of import detail: my game is a co-op shooter. Enemies do not need to be perfectly synched, they can be several unity units off. As long as players are shooting generally in the same direction to hit the same enemy, then I don't care if the positions of the enemy prefab are not exactly the same across all clients.

    What I've tried
    1. I've tried to look into a method that doesn't use network rigidbody and transform. Instead, I try to poll for differences in transform every few seconds. If the server transform is different from the client representation of the transform by some minimum threshold, I then perform a fast lerp to readjust the clients side to match the server. Before and during this readjustment, I store any physics events that occurred and reapply them when the readjustment is complete. I sort of have this solution working, but I can imagine some edge case scenarios where it doesn't work well.
    2. A regular old network transform and network rigidbody with rpc access to AddForce()

    The Ask
    Are there any robust ways to sync enemy rigidbody and transform data while also allowing clients to get fast and snappy knockback? Is my implementation the culprit of the problem and I am just overlooking how to allow clients to responsively manipulate the physics of the server-owned enemy?

    Extra thoughts
    I had seen that unity plans to create distributed authoring in netcode for gameobjects, would this solve my issue? Basically allowing my clients to process the physics of the enemies' knockback instead of the server? Or would this possibly pose new latency challenges due to having to switch authors each time a client hits an enemy? I'd imagine that whatever player is causing the knockback would be the author for the brief moment in which physics need to be applied, then ownership would be transferred back to the server or to another client who shoots it.

    The docs suggest using a custom Network Transform with a physics based interpolator - I tried this, but I need guidance. They toss this bit in at the end of the docs like its easy to do. I'm a bit frustrated with this server authoritative approach as it restricts the fun of my games responsiveness.
     
    Last edited: Mar 22, 2024
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,922
    Yeah, just make those enemy bodies non-networked then. ;)

    Say clients firing at these baddies, the clients all simulate the impact physics locally based on their local projectiles. Including any network synchronized projectiles from coop buddies. The client still informs the server about them shooting and in what direction etc and the server records any hits and deducts health and those state changes are synchronized back to clients but not the actual physics.

    So what happens on client side feels like responsive singleplayer behaviour but perhaps there will be a slight delay upon death, and players may notice that the coop players still firing at already dead baddies for a bit longer than expected, but none of that affects the fun.

    In coop you can apply these tricks because its about fun, not fairness. ;)
    It simply doesn't matter much that a player may fire more shots at an enemy than were necessary due to the delayed health sync.