Is it possible to update Physics.gravity at every FixedUpdate?

Hi,

I am developing a prototype for an iPhone game that involves moving the character up, down, left and right based on the tilt of the device. I am using iPhone’s gyroscope to get the tilt value and computing an appropriate vector for the gravity. The idea is to change the gravity based on the device’s tilt, so that the character (with a rigidbody) naturally responds to the physics of the game.

The problem I am facing though is that if I change the gravity at every fixedUpdate, nothing seems to be happening. The character does not move at all. BUT if I have Use Gravity = FLASE and instead of updating Physics.gravity, I add a force, I get perfect results! I really don’t want to turn off the gravity though, because my game is gonna be using a lot of physics and it’s going to be a huge mess if I have to simulate everything through code. Ideally, I’d like to know how I can get the gravity to update based on the gyro rotations. Please help!!

Here’s a snippet of my code:

public class Gyro : MonoBehaviour {

	void Update () {
	
		if (!Application.isEditor  SystemInfo.supportsGyroscope) 
		{
			m_gyroQuaternion = ReadGyroscopeRotation();
			m_eulerAngles = m_gyroQuaternion.eulerAngles;
			
			float sinAngle = Mathf.Sin( (m_eulerAngles.z) * Mathf.Deg2Rad);
			float cosAngle = Mathf.Cos( (180 - m_eulerAngles.z) * Mathf.Deg2Rad);
			
			m_gravityVector = new Vector3( -sinAngle, cosAngle, 0);

                        //The following line works perfectly, when I have my gravity turned off.
                        //transform.AddForce(m_gravityVector * 200);
			
		}
	}
	
	void FixedUpdate ()
	{
		Physics.gravity = m_gravityVector;
	}
	
	private Quaternion m_gyroQuaternion;
	private Quaternion m_eulerAngles;
	private Vector3 m_gravityVector;
	
}

The character has a rigidbody and I have ‘Use Gravity’ set to true.

Anyone, any thoughts about why it’s not working? Am I missing something? Any help would be highly appreciated.

Thanks!

That should work. Perhaps the gravity just isn’t strong enough to do anything?

It’ll need to be strong enough to get over the static friction threshold before it even starts to move (default is 0.4 for bodies without a custom physic material IIRC).

Unity physics acceleration forces are in meters (unity unit length of 1) per second squared. So in Unity, assuming correct scale, Earth surface gravity should be a vector with magnitude of 9.8 or something.

When working with Physics in Unity I always find it invaluable to use Debug.DrawLine or Gizmo lines to draw out the gravity forces I’m applying so I can make a better visual assessment of what my code is doing and if it’s acting the way I want it to.

I thought the same that the gravity isn’t strong enough. So I have tried all kinds of values from 100 all the way to 1000 to scale the gravity vector to make any difference. But the character just won’t move! I al totally lost. Also, I do have Gizmos drawn for the force vector and they are getting drawn as expected. I don’t know if that helps me in anyway, though :frowning:

I also tried setting gravity as follows: (just to see if it’s even possible to update gravity every fixedUpdate): I created a gameObject called Gravity. I then calculate the direction vector from the character and Gravity object. I normalize this vector to get a gravity vector ( and I do this every FixedUpdate). What’s interesting is that the character appears to be reacting to this gravity vector but only for a little while. If I start moving the Gravity object (left/right/up or down), I should expect the character to move differently. But it doesn’t. The character just stays at one place. So I kinda confused. Is it even possible to update gravity every frame?

Objects won’t respond to gravity if they’re asleep, so perhaps you need to use WakeUp().

–Eric

Eric,

Thanks for suggesting that! That totally worked for me :-). Apparently, rigidbodies sleep periodically during their life cycle for optimization purposes. No wonder it wasn’t reacting to any physics. So, now i have rigidbody.WakeUp() called in every frame along side updating the gravity. It gives me perfect results (which I am thankful for) but now I am worried about the performance. Any thoughts on that? Will keeping rigid bodies awake at all frames bring down my frame rate in the future?

If you check out your Physics settings (Edit → Project Settings → Physics) you could lower the “Sleep Velocity” and “Sleep Angular Velocity” instead of calling WakeUp(). If you decided to leave it how you have it now I would make a change so that instead of calling WakeUp() every fixed update:

if(rigidbody.IsSleeping()) rigidbody.WakeUp()

Even If you left it how it is now, I don’t see anything that would cause performance problems. But you can always test it!

Thank you for the advice. That makes total sense to me.