Physics.Simulate problem

I am using the Physics.Simulate method to run the game physics for a short period so I can record the positions of the objects and display paths for them, the problem is the results from when I use Physics.Simulate are different from when the physics are run normally. For example I set a ball rolling slowly, in normal game mode the ball will come to a stop in about 1s, but if I use Physics.Simulate the ball just keeps rolling, ie if I ran the Physics.Simulate for 30s the ball would be moving that whole time. What do I have to do to get the two to match. It looks like drag or friction are not being applied in Physics.Simulate.

I’m interested in a solution to this as well.

Meanwhile, you may want to look into recording their positions at runtime in a file…

Thanks for the reply but I am not sure how recording the positions into a file helps when the values I get from Physics.Simulate are wrong.

Record them at runtime, while the “real” physics engine is running. Just a thought.

Arr I see but no good in my case its for an aiming mechanic so you can see the potential results.

If I followed you correctly, the reason for the difference is that physics isn’t simulated for a long period of time using a single call, it’s typically called multiple times passing in the fixed-update time interval. Let’s say that’s 1/50 sec. This means for 30sec simulation you need to call it 1/50 * 50 * 30 times so that you get exactly what’d happens during auto-simulation updates for 30sec.

@MelvMay - Yes I understand that and I do do that but the results are totally different, it just seems like drag or friction isn’t being applied, a ball that will stop rolling in under 1s when the game us run will run for as long as Physics.Simulate is called, maybe they are not going to sleep or something but it is totally useless to me.

That is very odd. Know that this isn’t some special, separate code-path. There is no difference between the Unity main-loop calling this and you explicitly calling this via script. They both end up calling the exact same method in both 2D & 3D that performs the simulation and script callbacks etc. Indeed the player-loop calls ::Simulate(dt) but with a fixed-time and the only difference via script is that the “dt” is what you pass and the same call is made.

This makes what you’re saying very odd indeed. I am not sure what interactivity you’ve got set-up with physics objects but you could try to ensure that when you call simulate, you do it before any other scripts as this is how the physics simulation normally runs. I presume you’ve double checked that you’re passing in the fixed-update time-delta for however many times you call it?

There is nothing special going on, I just have a sphere which I apply a small force to which then rolls across a plane. When left to run normally it comes to a stop quickly, when Physics.Simulate is used it will just keep on moving no matter however many times Physics.Simulate is called, even when called 3000 times to simulate 30s worth of time. There are no other scripts changing the behaviour or adding in other forces.

So I’ve just put together a super simple project based upon your description: https://oc.unity3d.com/index.php/s/4oC8NjzKpmep1bi

Load-up the only scene and select the “Sphere” GameObject. In here you’ll find a simple script that allows you to select one of three simulation modes to run in:

  • Auto - Runs the simulation continuously forever

  • Manual - Runs the simulation with Physics.Simulate forever

  • Interval - Runs the simulation with Physics.Simulate for the Time Interval specified on the script property

If you select a mode then hit run and watch the sphere position end. Come out of play mode and select another mode then run again. Here, all three modes end-up with the sphere coming to rest at the same position.

If you get different results then that’s something you should report to the 3D physics team for sure. Feel free to reference this project too!

Hope this helps.

1 Like

Hello MelvMay!
I downloaded and tested your project. I’m trying to update physics in the normal update function (as seen in Unity documentation for Physics 2D [https://docs.unity3d.com/ScriptReference/Physics2D.Simulate.html]). However, then interpolation does not work.

This can be seen if you increase the fixed time step and toggle any interpolation method on a rigidbody, and simulate in the normal update function.

Interpolation works when running simulation in FixedUpdate, however it does not when called from the normal update function.

Any suggestions why the interpolation does not work when simulating from normal update function?