Need some assistance with dynamic gravity systems

I’m trying to get a dynamic gravity system up and running which can be toggled and modified on the fly. For example, in space scenes I want the majority of the scene to be 0g. However, when you’re inside something such as a ship or station, there should be gravity pointing towards the bottom of that particular object (which could have any rotation). When on the exterior of these objects I want to enable the ability of walking along that surface.

I know that I can change the specific direction of gravity on the fly using physics.gravity. My understanding though (correct me if I’m wrong) is that this will change the gravity direction of everything in the scene rather than just a specific object(s) in an area. I’m pretty sure that something as simple as the solution mentioned here will work, however the direction the gravity needs to pull is dynamic and may changed if the object/area rotates. So… anyone have any ideas on solutions to the issues here? If I use an empty game object’s transform to calculate the direction of gravity, the further you are from the center of the object the worse the problems will get (you will get pulled down AND towards the center). Is there any way to set up a volume/trigger who’s gravity is always pointing towards the bottom plane in the trigger?

For walking along the surfaces I’m thinking that I should be able to use an empty game object’s transform to determine the direction of gravity (by placing it a meter or so underneath the player). I’m thinking that this will change the direction of gravity based on the angle of the ground/surface beneath the player, but won’t have the issues mentioned above due to the much smaller area affected. Would this be the best way to approach it, or should I figure something out based on the surface/material used (i.e. attach directional gravity to all exteriors so that non-magnetic surfaces can be excluded)? The other big issue I see here is if you jump towards another object that has a different rotation (wall, ceiling - obviously not those specifically, I’m referring more to their placement compared to the player), your rotation will still be based off your original position, and isn’t going to rotate to face the same direction as the surface you’re trying to walk on.

If anyone has any good solutions or ideas, I’d love to hear them.

I briefly experimented with this. You basically have to completely replace the controller system. It seems to require gravity to be downwards. (And the system-wide gravity works on everything the same.)

What I had implemented was a system that exerted force on every FixedUpdate in the direction of gravity for that particular object. Initially this was a pair of scripts. 1 goes on the object, and the other goes on the point that you want gravity to be at. If the object is within the ‘gravity radius’ of the gravity point, then the script on the object would exert force towards the gravity point.

Getting more complex, I made it so that multiple gravity points were averaged, and they followed the whole ‘square of the distance’ thing that real gravity does.

Basically, it was Super Mario Galaxy’s gravity mechanic, at its simplest. (SMG is actually more complex by far… More like what you need.)

What I never got around to is what you want. You want gravity sources that pull in a certain direction from the player, and not towards a center point. I don’t think it would be that hard, but it’s a different idea than the other.

Get the normal of the face below your character and use the -Y axis as your vector to AddForce to the rigidbody. It also gives you an axis to keep your character capsule, which must be a rigidbody in this case and not a CharacterController, upright. If you spaceship surface is greebled a bunch then you may have to make a mesh collider to keep planes below continuous but aligning to the ships surface to assist in the effect.

HTH

Since I need to create a custom controller anyway it isn’t a huge issue. So did you use a single point on each gameobject or are you able to use something for a slightly larger area of effect? With larger game objects is there any sort of drag if you’re standing on the edges?

I used a similar system already to create hull breaches, but one of the issues I ran into is that if the objects being affected collided with an object (such as the edge of the rip in the hull) it would continuously pull the object until it finally got sucked through the geometry or would bounce away, and for some reason would then ignore the script. I was able to solve the second issue by constantly increasing the amount of force applied, but I could see the first one being an issue for any script that needs to have an effect longer than a few seconds or so. Could this have been due to the fact that I didn’t use FixedUpdate?

Thanks for the info, I thought I might have to use a system like that, but it’s good to get some confirmation before I get cracking on that part of code.

Edit: I was replying as you were ippdev. That sounds pretty solid as well. I’ll probably write up some code for both methods and see what works best.

Like the others have said, get the normal ‘up’ and apply a force in the opposite direction.

Inside the ship, this should be as simple as using the ships transform.up.

Outside the ship, you would have to first shoot a ray using the players -transform.up. This gives you the normal below. Then you use this face normal as ‘up’.

As far as moving, I use moveDirection = Vector3.Cross(Vector3.Cross(up, moveDirection.normalized), up)

The way this works, is it first gets your ‘right’ axis according to up and your movement direction, then uses this right axis, and up again to determine the proper ‘froward’ direction across your surface.

I am also a fan of Velocity Change.

Once you determine your movement direction:

if(useGrav){
	deltaVel.y -= (gravity * Time.deltaTime);
}

Since you are using a rigidbody, all of your movement forces should be handled in FixedUpdate.

FixedUpdate made a big difference for me. You should definitely try switching to that.

I didn’t experience any pulling issues like you describe, but I only experimented briefly with it. I was trying to use addForce to control the character, and this wasn’t working well at all. With a lot of futzing around, I was able to make it work barely okay. I was faced with rewriting it completely and manually moving the character, or doing something else. I ended up doing other things.

well another thing relating to gravity i found is that if you go to Edit>ProjectSettings>Physics (pretty much physics settings) in there you will see a gravity setting and the direction. still do i’m not so sure how to acces that one at runtime. now about about being able to walk along surfaces and of the such mainly i have seen people use rigidbodies since you can give them forces and unity has a force field type thing to simulate winds but if you have it stronger then it could be as similar to gravity.