# Creating smooth terrain and part terrain planet gravity. edit: for a physics based car now

It should be 0 if you are using custom gravity for the planet you need to pull the car inwards.

workspace.gravity is 0

this is what i mean

Ah, I see. Why can’t you use `LineForce` to apply the gravity separately then? I don’t think the car suspension should be entitled to managing gravity.

its not

each wheel has a bunch of vectors each with a purpose

forward, friction and right are nothing to do with gravity
up vector is the suspension force
grav vector is the gravity vector

causing this

Alright. From the video it looks like the car’s suspension is simply being clamped down to a positive value and not a negative value.

I don’t suppose this is the case, but you should check for it, because the constraints in the video disappear when this happens (meaning it is disabled).

the vector forces will only become 0 if no ground by the raycast is met
so i do this so it stops pushing on the vehicle because it aint touching the ground

the gravity force is always applied no matter what
i set the gravity back to 196.2 because i want the player and the vehicle to be the same

the workspace.Gravity is still 0
here a video of what is currently going on

update: scrap everything i said
just realized i dont need a gravity force at each wheel, plus the calculation of the force requires on where the force to be applied at the center of mass

so i did that, there is now only one gravity force in the center of mass of the entire model
now its just bouncing

1. Use EgoMoose’s gravity controller:
1. Store a list of positions for the center of the planets.
2. Each physics update:
• Get the nearest planet position
• Set the direction of gravity to be in that direction (planet position - player position) in the gravity controller
3. Done!

im now trying to get this working for my physics based car

i should edit the title…

edit:
force for the gravity on the Y is -294k (ish)
force for the suspension on the Y is somewhere above that (it changes a lot)

edit 2:
stiffness = 60000
damping = 5000
too much makes it bounce

stiffness = 40000
damping = 2500
too little

1 Like

Ah okay. To do that:

• Either set Workspace.Gravity to 0 or add a vector force to each assembly (with force: mass * workspace gravity) in the upwards direction to cancel the existing gravity
• Add a vector force to each assembly for the artificial gravity
• Every physics update:
• Get the closest planet
• Get the unit direction of the planet from the assembly’s center of mass
• Set the force to be unit direction * mass * desired gravity

I think you do need gravity for each wheel, because I’m pretty sure they’re separate assemblies

I also wouldn’t use raycasting because then the car wouldn’t do anything on hills and even walls (like slow down or stop). Instead I would pick a way to calculate the gravity at a point (like picking the closest planet from a list of planet positions).

You can calculate the artificial gravity forces to be assembly mass * workspace.gravity to get the fake gravity to be consistent with the regular gravity.

and no i dont need one for each wheel for now. im just trying to get this working with a perfect sphere. it will be easier to convert a perfect sphere to work with hills and mountains

raycast is a very important part of the vehicle without it i would have no idea where the ground is. this vehicle is all done through math there is no spring constraints or friction going. nothing is touching the ground (that can collide)

as seen in this video (second one): Creating smooth terrain and part terrain planet gravity. edit: for a physics based car now - #23 by bIorbee
the car bounces up and down. i tried fine tuning the suspension and damping but nothing will keep it stable

also at some point the car just decides to fall over

1 Like

That looks way more than 196.2 gravity. Are you sure you are calculating gravity correctly? Can’t you adjust the suspension’s stiffness and damping?

the reason is was way more is because there was 4 wheels applying it

the updated one looks more like the second video from this message: Creating smooth terrain and part terrain planet gravity. edit: for a physics based car now - #23 by bIorbee

yes i already tried changing the stiffness and damping, nothing i set it to worked; either it was too weak or too strong

You can try `BasePart.AssemblyMass` to get the mass then divide it by wheels.

thats already done. the gravoty is calculated the same way as before but this time just on gector force at the center of mass

``````-- base gravity (right now 196.2), workspace.Gravity is 0
local g = workspace.PlanetCenter.Gravity.Value
-- mass of the base. base is the only thing that has mass everything else is massless
local mass = base.AssemblyMass

-- upVector is a Unit vector
local gForce = g * mass * self.upVector
return gForce
``````

so heres the real issue and also im sending this up to clear up any confusion

the vehicle with the fake gravity works fine when the up vector is (0, 1, 0)
the current gravity is 196.2 and nothing is changed in this video except now the gravity points towards the center of the planet

i also turned off everything but the gravity and suspension force.

i had this bouncing glitch before and i fixed it by getting a better speed calculator. but now i tried to do that and it aint working.

what i currently have to calculate the vertical speed is this

``````-- self.attach is the attachment the vector force is attached to
-- self.upVector is the calculated up vector based on the planet
-- baseCF is the cframe of the base
-- base is an invisible part where all the forces are applied, also the only part with mass

function getVelocityAtPoint(part, worldPoint)
return part.Velocity + part.RotVelocity:Cross(worldPoint - part.Position)
end

-- without :Cross(self.upVector) it was much more bouncy than with
local velocity = getVelocityAtPoint(self.attach.Parent, self.attach.WorldPosition):Cross(self.upVector)
local verticalSpeed = baseCF:vectorToWorldSpace(self.upVector):Dot(velocity)
``````

this method seems to be more stable but still very bouncy

``````local velocity = baseCF:vectorToObjectSpace(getVelocityAtPoint(self.attach.Parent, self.attach.WorldPosition):Cross(self.upVector))
local verticalSpeed = baseCF:vectorToWorldSpace(self.upVector):Dot(velocity)
``````

this is very stable but flings the cart some times

``````local verticalSpeed = base:GetVelocityAtPosition(self.attach.Position).Y
``````

video of the method above:

this is then multiplied by the damping (just the dampened spring formula)
this works fine when the up vector is (0, 1, 0) but doesnt seem to work when it moves around.
i also tried making it (0, -1, 0) thinking that it doesnt work when X or Z isnt 0 but that didnt work either

so im lost at this point. i dont know what to do make it work with the correct up vector

1 Like

You need to have a multiplier for it and decrease it.

What do you mean by this? Do you mean that it prevents the vehicle from moving?

no its to the dampended spring formula modified for games

and no there is no multiplier to the velocity it doesnt exist

@BendsSpace @SubtotalAnt8185 im mentioning you two because you two are helping me out a lot with this

update #2 i fixed the issue within the last update but now a bunch more are now here

1st is the big and main one
the suspension force isnt applied directly up causing it to move around since the force is slightly pushing that way. (the video will make this make more sense)

this is a problem for two reason. 1 when going around the planet you speed up a ton and cant stop ever. 2 i dont want the car to slide around when stopped. when stopped the car should stay around the same place

video:

this is what i do to make it point directly up based on the gravity’s up vector
`data.upVector.Force = suspensionForce * Vector3.new(0, -upVector.y, 0)`
upVector is relative to its attachment

but since each wheel isnt at the same elevation this causing a slight change in the direction of all four of the vectors causing it to push back then the others push in the opposite direction and this just repeats with a never ending cycle

2nd issue
when getting into the vehicle (as seen in the video) the car just snaps down for no reason.
the gravity force does not change. i made sure the character is massless. i know for sure when handing over gravity control to the client, the client has the same values, and no variables were changed between the transfer

just for some reason when you get in it the offset (which is the distance between the vector force’s attachment’s position and the ground) decreases from 2.7 to 2.0. this causing the suspension force to be much larger (while not really impacting a lot) but this also is a stable 2.0 and never goes back to 2.7 where it should be. it just sits there causing the vehicle to be very low to the ground

i know everything works fine because i reuse the same module for the client and server. so i dont get whats wrong with that

i think i know how to fix this but it could be unoptimized since the idea is just doing gravity calculation and force appliance on the server and leaving the client to do the rest. this may help it but the problem is i give network ownership to the client.

gravity force calculation. every heartbeat this is added

``````-- if you really want to see this function
-- i dont understand it i just know how to use it
function getRotationBetween(u, v, axis)
local dot, uxv = u:Dot(v), u:Cross(v)
if (dot < -0.99999) then return CFrame.fromAxisAngle(axis, math.pi) end
return CFrame.new(0, 0, 0, uxv.x, uxv.y, uxv.z, 1 + dot)
end

function calculateGrav(base, upVector)
local g = workspace.PlanetCenter.Gravity.Value
local mass = base.AssemblyMass

local gForce = upVector.Unit * mass * g
return gForce
end

local upVector
local gravityDir = (planetCenter.Position - self.base.Position)
local rotateToFloorCFrame = getRotationBetween(self.base.CFrame.UpVector, -gravityDir, Vector3.new(1, 0, 0))

if gravityDir.Magnitude <= planetCenter.GravityDistance.Value then
upVector = -gravityDir.Unit
else
upVector = Vector3.new(0, 1, 0)
end
self.upVector = upVector

local gravForce = calculateGrav(self.base, self.upVector)
self.gravVector.Force = -gravForce
``````

thats the two main issues i have right now. i need some help solving them

1 Like

You need to subtract velocity from it to achieve damping.

I’ve made a chassis that uses the normal vector for this too. I just damped the dot product of velocity going perpendicular to the wheel, and this somewhat worked in my case.

However, what you could possibly do is take the average up vector of all of the wheels and apply it to all of them to smooth it out.

Probably because of network ownership. `SetNetworkOwner` should be used.

Though, you imply that you use this for the client and server, so I’m not sure.

this has nothing to do with the cycle
i said this. its getting pushed back and forth not up and down
i know how to make the suspension force i have done it many times before

this is how i get the velocity

``````local base: BasePart = self.attach.Parent
local baseCF = base.CFrame

local velocity = getVelocityAtPoint(self.attach.Parent, self.attach.WorldPosition)
local verticalSpeed = baseCF:vectorToWorldSpace(Vector3.new(0, 1, 0)):Dot(velocity)
``````

and gets applied like so

``````suspensionForce * Vector3.new(0, -upVector.y, 0)
``````

and its relative to its attachment. so its local up vector is directly perpendicular to the base
i dont think you understand whats wrong here. i will draw a picture

the circle is the planet, the red brick is the car, the black dots on the car are the vector forces, and the green arrows are their velocity

so when like this the higher up wheel is pushing UP AND TO THE LEFT this causing the car to drift in that direction.
but the lower wheel after getting pushed down will push back causing it going back to the right.

since the wheels are never aligned perfectly this causes the car to drift.

now this is easily fixed in cars that drive on flat ground and their up vector is always (0, 1, 0)
because their vector forces will always be relative to the world so they will always point straight up

but due to the up vector of the car never being consistent, and when upside down pushing up relative to the world will causing it to push in the direction of the planet instead of away from it

the player owns network of the car when getting in. i already said this