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

Resolved Possible to "instantly" fast-forward physics?

Discussion in 'Physics' started by UnbridledGames, Jan 4, 2021.

  1. UnbridledGames

    UnbridledGames

    Joined:
    May 12, 2020
    Posts:
    139
    Is there a way to run an object's physics through a certain point 'instantly'? I'm trying to position some objects randomly/naturally, and would like to "drop" them onto the ground, so they are laying in a somewhat natural, but randomized position, but I want to achieve this before they are moved into the view of the camera.

    Clearly I can pre-load them off camera, but I'd prefer not to have to stage them before hand and wait... some round objects roll around a bit and I want to be sure they are done moving before loading them in.

    Is this possible? How?

    I typed this out before I realized that it's pretty irrelevant to the question. Decided to just hide it instead of deleting it, in case the reasons behind it lead to a better answer.

    My app has a feature where you can scavenge for junk. When finding cans and broken bits of stuff out in the woods, the orientation could be all over the place. Up until now I've been using a script I wrote that throws the objects into the air, and once they land and stop moving, they are saved as a prefab, so the object can be in a 'natural' position on the ground.

    When the object is instantiated, the idea was to apply some random rotations to it so the same can isn't always appearing in the same orientation. That sort of works until you're working with cans that have been crushed... a flat can isn't going to naturally stand on it's side. So random rotations won't work.

    My thought is if, before the object is loaded into the scene, if I can drop it, let it land naturally, then move it in, I'd get more natural positioning of the items. But - I don't want them to be moving in the scene (the object once in the scene have no physics and do not react to the environment - they are static).

    So is there a way to 'fast forward' an objects physics and have it fall/settle/land all within a frame or two before it's loaded in?
     
  2. ShokTheIV

    ShokTheIV

    Joined:
    Nov 19, 2020
    Posts:
    17
    u can slow down the gravity for like 5 seconds
     
  3. tjmaul

    tjmaul

    Joined:
    Aug 29, 2018
    Posts:
    464
    You can manually simulate a couple of steps. This effectively jumps forward in time. Use Physics.Simulate to do this
    https://docs.unity3d.com/ScriptReference/Physics.Simulate.html

    Be aware that if you character is a rigidbody and it has a velocity, it will also teleport depending on the situation.

    Another way to achieve what you’re trying to do: Create an additional physics scene and add whatever necessary for the specific item you’re adding to fall into the correct position, so probably the terrain and some trees or stones. Then simulate the additional physics scene manually for a couple of seconds (you can also do that with the Simulate command). Now copy the item of interests position and instantiate it in your actual world.

    sorry if that’s a bit confusing but. It’s like a copy of a part of your original world for the sole purpose of placing an item.
     
  4. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
  5. UnbridledGames

    UnbridledGames

    Joined:
    May 12, 2020
    Posts:
    139
    Thanks for the tips - I haven't checked on this thread in a while as I dove into the code and figured it out on my own in the meantime. Used Physics.Simulate inside a loop - wasn't an issue for other physics because the scene itself doesn't use any. It's all AR, I just wanted to use physics to drop some objects randomly and "naturally". Put on a rigidbody, put it above a surface, Physics.Simulate until it stops moving, remove the rigidbody, move into place in the scene.

    Is it overkill? Absolutely! Has anyone ever complained "the trash in this game is always laying in the same looking pile, I want more natural looking piles of trash!"? Of course not! So why did I do it?

    Uh... because I could, and it was cool to do/learn/implement? *shrug*

    Overkill!
     
    Reahreic likes this.
  6. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    eh.. you know.. you could just solve it with a handfull of noise. (spawn chance, position offset, random rotation)
    this is a very good tool in the procedural toolset.

    classic case of right problem wrong solution right here imo.

    cool practice and good experience, like you said, so don't feel too bad, haha.
     
  7. UnbridledGames

    UnbridledGames

    Joined:
    May 12, 2020
    Posts:
    139
    Nope. I tried the position offset and random rotation thing. Problem is I'm working with a large pool of differently shaped objects. And the prefabs aren't all in the same orientation. What spawned this whole thing was I had a pack of prefab crushed soda/beer cans. They were all "upright". The least damaged ones would naturally be laying on their side 99% of the time, rotated 90 degrees around X. The most crushed ones would not be on their side - they'd be upright (or upside down). Mid-level crushed ones could be either upright, or on their side.

    All assuming the spawn was just 1-2 cans. If it was a pile of 15 of them, some would be leaning on each other.

    And some aren't cans at all and all have arbitrary positioning. Literally every prefab I used would have to be manually aligned, and which axes should rotate and by how much would need to be saved and implemented.

    And if and when I added new/different prefabs, it'd all have to be done again.

    OR... I make a method that loads any number of any size or shape prefabs, applies random spin to them, drops them between frames, then moves them into the scene, and I never again need to worry about processing the orientation and rotation of every single prefab I import for this use.

    That was entirely too much explanation. Anyway. I humbly disagree that it was the wrong solution. Overkill, for sure. WRONG? Nah.
     
  8. UnbridledGames

    UnbridledGames

    Joined:
    May 12, 2020
    Posts:
    139
    For anyone searching this in the future, the solution was:
    Physics.autoSimulation = false;

    while(true) {
    Physics.Simulate(.025f); // Anything much higher causes problems, it needs to be done in small steps, see docs
    if(frames or time or whatever I'm checking against)
    break;
    }

    Physics.autoSimulation = true;


    This will affect all physics in the scene. In my case nothing in the scene is affected by physics except for these objects as I'm making the piles, so not an issue.

    But thats how you manually fast forward physics.