Search Unity

Calling the physics simulation from C#

Discussion in 'Physics Previews' started by yant, Dec 6, 2016.

  1. marserMD

    marserMD

    Joined:
    Aug 29, 2014
    Posts:
    178
    There is only one way to do so:
    1) set all rigidbodies to be kinematic except for those you want to simulate
    2) make a physics step
    3) restore rigidbodies from being kinematic.
     
  2. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,064
    huh... I did not think about that. I actually like this approach

    I wonder what kind of cost the simulation of a kinematic rigidbody has, though. And what kind of cost toggling isKinematic has
     
  3. Stanchion

    Stanchion

    Joined:
    Sep 30, 2014
    Posts:
    259
    Yes I made an example of this http://hatebin.com/jegoqmeyqq

    However this is not viable at all for a game in production, it is a crazy amount of performance drop along with other complications that can come up. I think Unity will add "partial scene simulation" like they mentioned.
     
  4. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,064
    This is a case where the Job System and ECS would really shine, if they do allow controlling rigidbody.isKinematic in jobs

    Was the cost mostly in the iteration on all rigidbodies, or in the actual Simulate()?
     
  5. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,474
    How will Physx become deterministic? I believe it will be necessary because future Unity is designed to be deterministic.
     
  6. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,064
    From what I've read, physics determinism isn't really something that seems like a viable thing to pursue (but I could be wrong). Seems like achieving determinism would result in a general performance degradation even in the best case scenario
    https://gafferongames.com/post/floating_point_determinism/

    Physics can be networked just fine without requiring determinism
    https://gafferongames.com/post/snapshot_interpolation/
     
    Last edited: Mar 12, 2018
  7. Stanchion

    Stanchion

    Joined:
    Sep 30, 2014
    Posts:
    259
    The main point of this feature in my mind is to allow for client side prediction for rigidbodies. Without a way to "fast foward physics" there is no way to "catch up" after getting a correction from the server. Even with the best optimizations, a client having to do a crazy amount of calculations constantly won't in a remotely performant manner. Unless PhysX or something else makes this impossible, Unity needs to expose a way to step physics on specific rigidbodies so that this can be done.
     
    recon0303, GarthSmith and chiapet1021 like this.
  8. marserMD

    marserMD

    Joined:
    Aug 29, 2014
    Posts:
    178
  9. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    290
    Everything that was planned at some point, never escapes the backlogs I guess :)

    Back to the topic, there will be a release coming real soon (TM) that supports multiple physics scenes. That way you'd be able to control the simulation of all the bodies on a much more granular level. Stay tuned.
     
    Antypodish, Jes28, sanmn19 and 11 others like this.
  10. marserMD

    marserMD

    Joined:
    Aug 29, 2014
    Posts:
    178
    If you are going to predict client-side character, the most common way is to use somewhat custom character physics anyway, IE involving no rigid bodies. Making a fully physics controlled character is a pain and none of the big studios do so.

    Unity's built-in CharacterController is kind of lame, but you can take a look at https://roystanross.wordpress.com/downloads/ which is really good.
     
  11. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,474
  12. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,064
    I can confirm this one is simulatable granularly. It is also close enough to determinism for networking (as deterministic as floats allow)

    Basically, there's:
    KinematicCharacterSystem.Simulate(deltaTime) // Simulates all characters
    KinematicCharacterSystem.Simulate(arrayOfCharacters, deltaTime) // Simulates only the specified characters
     
  13. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,158
    While this is getting bit off-topic, I'd want to share my experiences on physx determinism:

    I've done some tests on PhysX 3.4 determinism on Unreal, I implemented fixed timestepping for UE4 (as they don't have that by default) and exposed the new PhysX 3.4 enhanced determinism flag. Afaik, latter only matters if you introduce or remove physics objects during the simulation so don't get too excited about the name, it just guarantees PhysX runs things internally at same order even if physics scene evolves elsewhere. I know Unity is still stuck on PhysX 3.3.3 but I suspect it has still same shortcomings as the newer one, unless they've messed up something with the upgrade.

    So to get to the point, in my tests PhysX (3.4) was completely deterministic on my own computer when I started the same simulation again by resetting the same level, I made a test scene that had things on it that are making PhysX sim usually undeterministic (plenty of on the edge + dynamic collisions) and also added my own physics force driven flying saucer there. I could repeat this as many times I wanted and it would always simulate exactly the same way (again, only tested on one computer).

    But I did notice that if I ever set physx rigidbody values myself, even like just read the physx objects transform and write the exact same value between two physics steps (without altering any velocities or other physics properties), determinism went off eventually (chances for this became bigger the more times I did this during the simulation). And to those who don't know this, to get perfectly deterministic results on resim, you'd need to have 100% same float values, even if your last digit from the float drifts off, your collisions can bounce into totally different direction. I noticed this being also what happened on my tests when I manually set the rigidbody transform. I debugged this from PhysX side too and there were bunch of math operations that could have done this, you can't just set PhysX transform internally so it doesn't do bunch of operations for the vector values (every multiplication etc you do back and forth with floats makes it prone to change it's value a bit due floats limited accuracy). After this point, I didn't even try to make PhysX simulation fully deterministic anymore as it wasn't clearly designed for that.

    Worth noting that when dealing with netcode and physics, you probably couldn't afford to sync the uncompressed physics transforms all the time anyway, so this isn't as huge issue as people would initially think, you'd still need to correct the physics sim somewhat.

    Also, to what others mentioned about custom logic for netcode characters is what most are doing anyway, but determinism isn't IMO the main factor for this, you just get more control over the char which is mandatory for good gameplay experience. For example, Unreals built-in characters that do full clientside prediction and netcode stuff automatically are actually very undeterministic, they just correct the results ASAP so people don't notice any issues (when things work like they should, anyway).

    Finally, in case some people missed, Glenn Fiedler wrote this nice post about Unity and physics networking (he didn't use server authority for this so it's bit different from the topics covered in this thread but many of his observations about limitations are still relevant here as well): https://developer.oculus.com/blog/n...orking-a-stack-of-cubes-with-unity-and-physx/. Maybe that can give some some new ideas on how to solve things when we get those additional physics scenes.

    PS. Still wishing Unity would expose PhysX Contact Modification -callback
     
    Deeeds and PhilSA like this.
  14. Stanchion

    Stanchion

    Joined:
    Sep 30, 2014
    Posts:
    259
    Yass.
     
  15. Leuthil

    Leuthil

    Joined:
    Jul 26, 2013
    Posts:
    94
    You might just be the saviour of UNET.
     
  16. AurimasBlazulionis

    AurimasBlazulionis

    Joined:
    Aug 13, 2013
    Posts:
    209
    This is good news. Firstly, that you can actually control the physics loop yourself now. And secondly, that (the important for efficient and secure multiplayer) of controling which objects should be simulating is coming. Both of these make rigidbody controllers feasible for fast-paced server-authoratitive networking.
     
    Stanchion likes this.
  17. Stanchion

    Stanchion

    Joined:
    Sep 30, 2014
    Posts:
    259
    Any update on this? Can we expect this after 2018 out of beta?
     
  18. recon0303

    recon0303

    Joined:
    Apr 20, 2014
    Posts:
    1,598
    Ya I would love to know as well.
     
  19. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    1,920
    I'm working on both the 2D and 3D physics multi-world support which is mostly done (at least the complex bits). It's currently targetted to 2018.3 alongside other features that require it so isn't likely to get pushed back.
     
    AtomiCal, laurencew, Jes28 and 7 others like this.
  20. cemnahit

    cemnahit

    Joined:
    Dec 26, 2012
    Posts:
    38
    That's great news!
     
  21. Stanchion

    Stanchion

    Joined:
    Sep 30, 2014
    Posts:
    259
    2018.2 is out, can we expect a 2018.3 beta with this feature soon?
     
    DMeville likes this.
  22. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    290
    Yes. 2D is already in, and 3D is coming just a bit later during the cycle.
     
    GarthSmith likes this.
  23. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,474
    I'm not sure how this works, what is the feature and why would I want it? would love to know more (question directed to anyone really).

    Because I figure an island is a cluster of nearby rigidbodies, so a world must be a collection of islands totally separate from another world...
     
  24. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    1,920
    Both Box2D and Physx can create isolated physics scenes which don't interact with each other and can be queried/simulated in isolation from each other. This feature simply exposes the ability to create isolated physics scenes.

    In Unity then, the feature allows you to ask for a "local" 2D and/or 3D physics world when creating/loading a UnityScene. This means the GO or more specifically the physics components added to those GO in that scene will either be added to the default physics world (the only thing available in current Unity releases) or the "local" physics world associated with that UnityScene.

    This means that you can have a UnityScene that is either using the default physics scene or a local physics scene isolated from all others. When you add a GO to that scene, any physics components are added to the internal physics scene associated with that Unity scene. You can query them or simulate them in isolation from each other.

    For instance, you could create a scene and specify that you want a local 3D physics scene. You can then add GO with physics components into the scene and simulate/query it. You can then unload the scene and all the GO and physics components are removed. None of this will affect other scenes or the default scene we create for you.

    Here's a quick video showing a teste where we use a separate scene to predict where the balls on a pool table will end-up:
     
    cemnahit, Stanchion, M_R and 3 others like this.
  25. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,474
    Wow that is useful. And I can think of a number of things I dropped from our project because it did not exist.

    One thing I'm not super clear on is - is it tied to scenes? Would be nice to have a few worlds within the same scene, otherwise to get that we would have to additive load a ton of scenes... (I probably just read it wrong!)

    Edit: I read it wrong! Thanks.
     
  26. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    1,920
    > One thing I'm not super clear on is - is it tied to scenes?
    Unfortunately yes but this was the only real way to seemlessly add this feature without any extra API to manage it. It's also immutable in the sense that you specify a "local" 2D/3D physics scene at the point of creating/loading the scene and you cannot change that once it's created/loaded.

    It's possible for us to potentially add a list of physics scene per UnityScene but that needs the notion of an active physics-scene rather than the existing notion of an active UnityScene only for use when you simply instantiate a GameObject/Prefab.
     
  27. dante_voidalpha

    dante_voidalpha

    Joined:
    Apr 23, 2016
    Posts:
    1
    Will this change also make it possible for Time.timeScale to be scene relative? So I could pause the GameObjects in one scene and have another scene keep going at normal speed?
     
  28. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    1,920
    Time.timscale isn't related to multi-scene physics. You can however simulate each physics scene individually at whatever time-step you desired.
     
  29. hangemhigh

    hangemhigh

    Joined:
    Aug 2, 2014
    Posts:
    56
    Hey MelvMay, I want to thank you for your work. I've been using this lately for networking game and predication purposes and it works well.

    I have a question about physics and I think here is the best place to ask.

    Is it possible to make a have a function that takes a destination position and time in seconds then returns a Vector3 force required to move the Rigidbody to that destination position in that x seconds?

    For example, let's say I want to play a penalty kick in a soccer game and I want to use physics with the AddForce function to kick the ball. I know where I want to kick the ball which is destination pos (0,40,4). I want the Rigidbody to move to this destination pos (0,40,4) within 2 seconds.

    Maybe an overload of the Simulate function:

    Code (CSharp):
    1. Vector3 Simulate(Vector3 destination, float time)
    2. {
    3.     Vector3 force =???
    4.     return force;
    5. }
    Then it can be used as so:

    Code (CSharp):
    1. //Get required force to reach destination pos in 2 sec
    2. Vector3 requireForce = Physics.Simulate(new Vector3 (0,40,4), 2);
    3. //Kick ball
    4. rigidbody.AddForce(requireForce);
    -----

    Please don't think we are lazy and want everything to be done for us. We currently use MovePosition and MoveRotation to accomplish it and it works but not realistic at all. We think this something a new feature can solve.

    One of our programmers talked about using PID to accomplish this but I think that's crazy. It would take so much time for the calculation to finish.

    Is this something you plan to do in the feature? It won't only be useful to us but to many other programmers too. I can see this being used to develop realistic physics powered sports games in Unity. Countless of other things to do with this.
     
    Last edited: Jul 11, 2018
  30. AurimasBlazulionis

    AurimasBlazulionis

    Joined:
    Aug 13, 2013
    Posts:
    209
    Ignoring collisions and such you can rearrange some physics formulas to get the expected result in linear time. Most notably, horizontal (xz) axis always moves at a constant speed (-drag). So you need to calculate the speed needed to reach the point in t seconds and simply the force needed to achieve that speed. When taking gravity into account, you are basically solving a basic f(x) = ax^2 + bx + c formula. This will get the expected result apart from small drag which could be taken into account of or be so insignificant to be noticed.

    With collisions, however, there is no way to get the exact force needed to reach a point without a lot bruteforcing.
     
    hangemhigh likes this.
  31. Stanchion

    Stanchion

    Joined:
    Sep 30, 2014
    Posts:
    259
    Just to clarify, which release in 2D already in?
     
  32. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    1,920
    2018.3

    Both 2D & 3D are now in that version.
     
    Stanchion and GarthSmith like this.
  33. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,158
    Is there any info when to expect 2018.3 betas to arrive? Also we probably don't get public access to alphas?
     
  34. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    1,920
    The schedule currently says beginning of August 2018 for publishing of 2018.3.0b1.
     
  35. Roni92pl

    Roni92pl

    Joined:
    Jun 2, 2015
    Posts:
    266
    @MelvMay @yant
    Im wondering if it's better for performance to use 2 worlds(physx scenes) instead of e.g two layers that will never interact.. Better threading, less aabb tests, any other advantage?
     
  36. cemnahit

    cemnahit

    Joined:
    Dec 26, 2012
    Posts:
    38
    Will you be sharing the billard pool test that you showed us to shorten our learning curve somehow? Thanks
     
    Jean-Fabre, yant, Bas-Smit and 2 others like this.
  37. Bas-Smit

    Bas-Smit

    Joined:
    Dec 23, 2012
    Posts:
    109
    You can find some interesting leads here http://hyperphysics.phy-astr.gsu.edu/hbase/lindrg2.html

    It works slightly different in Unity, but from the equations linked above the following methods can be derived. The method you need isnt implemented but it should be possible to derive it from the last method (ai to the rescue):

    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3.  
    4. public static class Predict
    5. {
    6.     public static float Distance(float speed, float drag, float time)
    7.     {
    8.         var characteristicTime = 1 / drag;
    9.         return (float) (speed * characteristicTime * (1 - Math.Pow(Math.E, -time / characteristicTime)));
    10.     }
    11.  
    12.     public static float Speed(float speed, float distance, float drag)
    13.     {
    14.         var characteristicTime = 1 / drag;
    15.         var time = Time(speed, distance, drag);
    16.         return (float) (speed * Math.Pow(Math.E, -time / characteristicTime));
    17.     }
    18.  
    19.     public static float Time(float speed, float distance, float drag)
    20.     {
    21.         var characteristicTime = 1 / drag;
    22.         return (float) (characteristicTime * Math.Log(characteristicTime * speed / (characteristicTime * speed - distance)));
    23.     }
    24.  
    25.     public static Vector3 Position(Vector3 velocity, float drag, float time)
    26.     {
    27.         var characteristicTime = 1 / drag;
    28.         return velocity * characteristicTime * (float) (1 - Math.Pow(Math.E, -time / characteristicTime));
    29.     }
    30.  
    31.     public static Vector3 Position(Vector3 velocity, float drag, float time, Vector3 force, float mass)
    32.     {
    33.         var terminalVelocity = force / drag / mass;
    34.         var characteristicTime = 1 / drag;
    35.         var compound = (float)Math.Pow(Math.E, -time / characteristicTime);
    36.         return terminalVelocity * time + velocity * characteristicTime * (1 - compound) + terminalVelocity * characteristicTime * (compound - 1);
    37.     }
    38. }
    Edit: couldnt resist to play around with it, in all these methods drag can't be 0 btw...

    Code (csharp):
    1.  
    2. using System;
    3. using UnityEditor;
    4. using UnityEngine;
    5.  
    6. public class NewBehaviourScript : MonoBehaviour
    7. {
    8.    public Transform Target;
    9.    public float Time = 3;
    10.    float _startTime;
    11.    bool _started;
    12.    Rigidbody _rb;
    13.  
    14.    void Start ()
    15.    {
    16.       _startTime = UnityEngine.Time.realtimeSinceStartup;
    17.       _rb = GetComponent<Rigidbody>();
    18.       _rb.isKinematic = true;
    19.    }
    20.  
    21.    void Update()
    22.    {
    23.       var t = UnityEngine.Time.realtimeSinceStartup - _startTime;
    24.  
    25.       if (!_started && t > 1)
    26.       {
    27.          _started = true;
    28.          _rb.isKinematic = false;
    29.          _rb.velocity = Velocity(Physics.gravity, _rb.drag, Time, Target.position - transform.position, _rb.mass);
    30.       }
    31.  
    32.       if (t > 1 + Time)
    33.          EditorApplication.isPaused = true;
    34.    }
    35.  
    36.     static Vector3 Velocity(Vector3 force, float drag, float time, Vector3 target, float mass)
    37.     {
    38.         var compound = (float)Math.Pow(Math.E, drag*time);
    39.         return (drag * drag * mass * target * compound + force * (compound * (1 - drag * time) - 1)) / (drag * mass * (compound - 1));
    40.     }
    41. }
    42.  
    note that you need to supply a time, so you will have to iterate on that to get an acceptable velocity
     
    Last edited: Aug 8, 2018
    vizgl likes this.
  38. cemnahit

    cemnahit

    Joined:
    Dec 26, 2012
    Posts:
    38
    Hi, is there any update on the new Physx implementation and the beta version?
     
  39. Stanchion

    Stanchion

    Joined:
    Sep 30, 2014
    Posts:
    259
    Some at Unity told me beta would be out in a week around 2 weeks ago, so I expect soon.
     
    cemnahit likes this.
  40. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,158
    I'm bit puzzled about this, first 2018.3 beta released and there's now PhysicsScene but I can't figure out any logical way to add gameobjects to custom physics scene. API itself is really stub, there's basically only Raycast and Simulate, I couldn't see any option on Object.Instantiate either, and nothing new on GameObject itself. So the question is, how should we define what gets included in the custom PhysicsScenes of our own?
     
    dante_voidalpha likes this.
  41. AurimasBlazulionis

    AurimasBlazulionis

    Joined:
    Aug 13, 2013
    Posts:
    209
  42. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,158
    I dug the API, this is giving more info now https://docs.unity3d.com/2018.3/Documentation/ScriptReference/SceneManagement.LocalPhysicsMode.html, will report back if I get this thing running :)

    Worth noting that 2018.3b API docs are still missing quite a few things related to this, for example
    LoadSceneParameters is missing overloaded entry for
    there's also no mention of:
     
    Last edited: Sep 17, 2018
    yant likes this.
  43. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,158
    So, figured it out, here's my test script and gif how it works there:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.SceneManagement;
    3.  
    4. public class PhysicsSceneTest: MonoBehaviour
    5. {
    6.     PhysicsScene localPhysicsScene;
    7.  
    8.     void Start()
    9.     {
    10.         var loadParams = new LoadSceneParameters(LoadSceneMode.Additive, LocalPhysicsMode.Physics3D);
    11.         Scene localSimScene = SceneManager.LoadScene("PhysScene", loadParams);
    12.         localPhysicsScene = localSimScene.GetPhysicsScene();
    13.     }
    14.  
    15.     void FixedUpdate()
    16.     {
    17.         Physics.Simulate(Time.fixedDeltaTime);
    18.         localPhysicsScene.Simulate(Time.fixedDeltaTime * 0.2f);
    19.     }
    20. }


    The issue here is then that you need basically only ever to have physics on your "local physics" scene as this will mirror everything in that scene, including rendering, lights etc.

    Edit: I've now worked around this by disabling the mesh renderers for the locally simulated physics scene after it's done loading, still wondering if there are better ways to handle this.
     
    Last edited: Sep 17, 2018
    dante_voidalpha likes this.
  44. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    290
    Extensions being marked undoc is being fixed right as we speak. I guess there's nothing stopping us from sharing the billiards demo really if there's still any interest.
     
    cemnahit, Jick87, Stanchion and 3 others like this.
  45. cemnahit

    cemnahit

    Joined:
    Dec 26, 2012
    Posts:
    38
    Please share the billiards demo, thank you.
     
  46. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,474
    Are there any optimisation opportunities with multi scene physics, or is it still better to have one scene in that respect, so long as they're on different layers?

    My feeling about multi scene is - I can just make another scene and spawn some objects that are totally different and it'll be the same performance. The purpose is so we can run them at different rates from the main scene I suppose?

    What are more use cases?
     
  47. rizu

    rizu

    Joined:
    Oct 8, 2013
    Posts:
    1,158
    I think they added it mainly for people to be able to do server authoritative physics easier. It's possible already with the manual physics scene simulation but it gets increasingly more difficult the more physics rigidbodies you have. Now that you can simulate things on separate scenes, you can simulate the corrections on another scene without disabling bunch of objects back and forth from the main scene.

    One case I could imagine as well is if you need some visual physics sim that can run at lesser or higher update rate and don't need to interact with the whole scene. Cloth and destruction would be both good candidates for use case like this and is what UE does (or at least used to do). In theory you could run all kinds of visual sims completely isolated now if needed (without having really huge collision matrix setup).
     
  48. Roni92pl

    Roni92pl

    Joined:
    Jun 2, 2015
    Posts:
    266
    I would even extend that question - how about completely async physx simulation on separate thread? I know we can already have separated upate frequenty for physx engine but we still 'pay' for it on main thread. Cuz I was thinking about runing separate application with physx and communicating it with unity to achieve this, but I dont know how feasible that idea is.
     
    hippocoder likes this.
  49. Stanchion

    Stanchion

    Joined:
    Sep 30, 2014
    Posts:
    259
    Here's my first attempt using the new 2018.3 beta for Server authoritative physics players with client side prediction. In the video I am testing with 200 ms latency. I don't do any physics syncing to proxies yet so collisions are a little off.

     
    Jick87 likes this.
  50. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    83
    Am I correct in assuming that physics scenes can start as static copies of a state (snap shot) of the current physics scene graph which can be bufferd up and raycast against?

    If so this is exactly what I was talking about earlier in the thread and would allow cheap and robust anti-lag for weapons fire. As well as having applications in multi-threaded raycasting.