Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

2D: Interpolating while keeping physics simulation deterministic.

Discussion in 'Physics' started by Or4nge, Jan 5, 2021.

  1. Or4nge

    Or4nge

    Joined:
    Oct 3, 2018
    Posts:
    2
    Hello,

    my name is Matthew, I'm fairly experienced with Unity and programming in general but I'm at my wits end here:

    Background
    =========

    I created a game that is completely randomly generated.
    The game is heavily physics-dependent.
    I log every user input together with the #FixedUpdate it occurred, if they happen in between (like touch controls) I put them in a queue and apply them on the next FixedUpdate.

    So basically if I restart the game and use the same seed and replay the user inputs on the exact same #FixedUpdate they occurred I should get the same result every time, no matter how fast I replay or how high my frame rate - but that's not the case.
    If I disable Interpolate for all rigidbodies however I seem to get the same result every time.

    I added a small script to my player that checked if the position changed between physics updates and they do change when interpolation is enabled but do not change when interpolation is disabled so I guess interpolation is the culprit here as it makes my game frame rate dependent.

    TLDR: If you enable interpolate for any RigidBody2D in the scene the physics simulation becomes nondeterministic but I need determinism for my game.

    Problem
    ======

    Now my actual problem: How do I interpolate efficiently for visual smoothness without messing with the repeatability of my game?

    Linear movements are not hard to interpolate, but non-linear movements get hard.

    Current (probably inefficient) Solution
    ============================

    My current solution which works but adds another rigidbody and collider for every dynamic rigidbody/collider in the scene:

    1. Move Sprite/MeshRenderer from original GameObject (OGO) to separate "render" GameObject (RGO).

    2. Copy rigidbodys and colliders from OGO to RGO. Enable interpolate for RGO.

    3. Put RGO on a new Layer that collides with same Layers as the original one but not with the original one.

    4. Sync position and speed of OGO to RGO every FixedUpdate.

    5. Apply velocity and force changes to OGO also to RGO.

    So far so good but now I basically doubled the number of dynamic rigidbodies and colliders in my scene.

    Does anybody know more efficient way?

    What doesn't work
    ==============

    lerp: works for linear movements but as soon as forces are involved (like gravity) this makes things actually worse.
     
    Last edited: Jan 5, 2021
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,533
    Interpolation doesn't affect physics, it affects the Transform pose only and is purely a rendering improvement. When using it, the Transform interpolates (between fixed-update during each update) from the last Rigidbody2D pose to the current one. If your calculations use Transform.position/rotation then you're using a frame-dependant reference therefore you should always use the actual body pose i.e. Rigidbody2D.position/rotation.

    Again, there's absolutely nothing in interpolation that affects physics and certainly not determinism.
     
    Or4nge likes this.
  3. Or4nge

    Or4nge

    Joined:
    Oct 3, 2018
    Posts:
    2
    Hello,

    thank you, your answer was extremely helpful.

    I removed every usage of transform.position / transform.rotation and that indeed made everything a lot better.

    After setting up a fixed Script Execution Order I do indeed get the same result every time I replay a game down to the last decimal place.

    Can't believe all the thread that dealt with repeatability never mentioned that the transform should not be used and script execution may be different after reloading a scene.

    Thank you!
     
    MelvMay likes this.