Stop physics without using Time.timeScale = 0?
Asked Answered
R

7

0

Short of makinga ll bodies in a scene static is it possible to stop physics updates from happening without disabling time altogether?

Regularly answered 20/11, 2023 at 10:28 Comment(0)
D
0

Well you can set a Rigidbody’s Is Kinematic property to true to stop its automatic world interaction.

There’s many cases in which that would not suffice, but perhaps in your case it’s enough.

Whenever you want to ‘stop motion’, you will need to cycle all relevant scene objects and their Rigidbodies, and set their IsKinematic attribute to true.

Derangement answered 20/11, 2023 at 10:30 Comment(5)

Yeah I ended up doing as you suggested and saving the velocities of all rigid bodies so I could restore them after making them unkinematic.. pity ther eisn't a more elegant solution (i.e. halting physics by timestep).

Regularly

Have you added the comment to the wrong answer, or am I not understanding you correctly?

Quadragesima

I was justing adding to what you were saying, setting a rigidbody to kinematic doesn't only freeze dynamic bodies but also takes away their velocities so I had to save them then restore them on making them dynamic again...

Regularly

Ok, my misunderstanding then

Quadragesima

I'm happy that you sorted it out, Jabber. Well done.

Derangement
Q
0

I think it is possible to set the global Physics.sleepVelocity and Physics.sleepAngularVelocity to very high. this way your rigidbodies will fall asleep ignoring the system. But in order to get them back, you need to Awake all your rigidbodies I guess after setting the sleep parameters back.

Quadragesima answered 6/6, 2023 at 1:41 Comment(0)
M
0

There are many ways to make an object static, the following are in my opinion the best:

Roamcel’s method doesn’t actually help performance, since you would making the objects kinematic will make it have to check for collisions regardless.

Martijn Hendriks’s method is fine but not the greatest. If you were to go down this path you would be better off setting these settings indiviudally. Rigidbody.sleepAngularVelocity and Rigidbody.sleepVelocity.

Moonrise answered 11/11, 2011 at 6:22 Comment(1)

In some cases it might be sufficient to deactivate the rigidBody containing GameObject, provided you don't have any renderers or other components attached (this is my case, i have rigidBodies separated from actors and actors being "springed" to their rigidBodies for smoothing lag ) and all rigidBodies are parented to single gameObject so all i have to do is call SetActiveRecursively and all my physics stops

Ayers
E
0

For me the problem was a little more complex :
I had to pause a Gameobject’s Rigidbody and resume it in order to have an animated pause menu.

So, to fix it I proceed as follows :

  1. Save your rigidbody.velocity (instance)
  2. Pause the rigidbody using rigidbody.Sleep() or rigidbody.isKinematic = true (both on your rigidbody instance)
  3. Wait until the player wants to resume…
  4. Resume the rigidbody using rigidbody.WakeUp() or rigidbody.isKinematic = false (both on your rigidbody instance)
  5. Set up your rigidbody.velocity (instance) with the one you saved at the first step

Here is an exemple :

using UnityEngine;
using System.Collections;

public class Example : MonoBehaviour {

    private Vector3 velocity;
    
    void Update () {
		if (Input.GetKeyDown(KeyCode.Space)) {
			// Pause the game when the player hit the Space key
			velocity = rigidbody.velocity;
			rigidbody.isKinematic = true;
		} else if (Input.GetKeyUp(KeyCode.Space)) {
			// Resume the game when the player release the Space key
			rigidbody.isKinematic = false;
			rigidbody.velocity = velocity;
		}
	}
}
Evergreen answered 6/6, 2023 at 2:9 Comment(2)

Uhm, isn't that exactly what chillypacman used as solution? Have you read his comment on the selected answer? Also you do not save the angularVelocity of the rigidbody. If your objects aren't rotated by forces that might be not important, but for a general solution it should be included.

Eisen

I would argue that this answer is more complete. As just making an object kinematic is not sufficient to enable an object to be reactivated retaining the previous state of movement.

Ashurbanipal
F
0

Edit->Project Settings->Physics->auto simulation unable

Florous answered 6/6, 2023 at 4:21 Comment(1)

As of Unity 2017+, this should be marked as the better correct answer now. Thanks! (more info on Physics.autoSimulation -- https://docs.unity3d.com/ScriptReference/Physics-autoSimulation.html)

Shipping
T
0

For those who what to pause 2D engine programmatically without changing properties RigidBody2D and whatsoever, just use:

Physics2D.autoSimulation = false;// to pause

and

Physics2D.autoSimulation = true;// to resume.
Tolbutamide answered 20/11, 2023 at 10:31 Comment(0)
K
0

In my case, Sleep() was not enough as the objects can start moving even if not set to Wake() yet. What worked for me is saving the Rigidbody velocity and angular velocity and then setting the freeze constraints. That way you don’t need to change anything else in the program.

Here is the code:

void Animate(bool on) 
{
    if (on)
    {
        rb.constraints = RigidbodyConstraints.None;
        
        // Restore velocities
        rb.velocity = savedVelocity;
        rb.angularVelocity =  savedAngularVelocity;
    }
    else
    {
        //Save current velocities
        savedVelocity = rb.velocity;
        savedAngularVelocity = rb.angularVelocity;
    
        rb.constraints = RigidbodyConstraints.FreezeAll;
    }
}
Kutch answered 20/11, 2023 at 10:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.