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
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
i already made the controller for the player
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
Ah okay. To do that:
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
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
@SubtotalAnt8185 @BendsSpace update
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
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
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
I did not say it needed to. Damping can be in any direction.
I donât think itâs the wheels, but rather the terrain. Terrain is not perfectly smooth. Maybe you could have a sphere inside the terrain that you use to raycast to and then you blacklist terrain from it.
you still arent understanding the issue
the issue is the car while on a slope will fall backwrads down it (or forwards)
this is due to the suspension force which is aligned with the car and not the global up vector
the spring force can be deconstructed into two vectors, shown in yellow (yellow forces are not rotated correctly to make it easier to see)
first is the up force. this pushes up to keep it from just laying on the ground.
next due to the up vector of the car, there is a new backwards force that is happening
this pushes the vehicle backwards which basically makes it roll down the slope
there is also a friction force applied for rolling friction. this isnt enough to keep it from rolling down the slope
so the solution is to figure out how to scale the rolling friction force enough so it makes it not roll down the slope.
i seen this done before in math through free body diagrams but i cant figure out how to code one in roblox
here is an example of a free body diagram
this picture was rotated so the camera is now rotated based on the rotation of the car
the car is still on the slope (as seen with the gravity not pointing donw)
there is also the theta symbol (Î)
this is what im trying to calculate and i think i know how to calculate it by
taking the raycast hit normal inverted
then calculating the angle between the gravity unit vector and the normal
this gives around 17 degrees which makes sense since they are pretty close together
now the problem is how do i scale the rolling force so now when on a slope the car wont fall down
how would i counter the yellow force in this picture?
so thats what i been trying to do for the past 12 hours
no i cannot just extract the yellow force, since the suspension force actually has no force there. its just the rotation of the car that causes that. since the suspension force is always pointing up relative to the car, when the car is rotated this causes the spring force to ârotateâ with it even though no force is being applied in that direction
this has nothing to do with damping or the suspension force, or even the gravity
all of it is to do with the rolling force not applying enough force for it to stay on the slope
now you may say âwhy not make the spring force global to the worldâ well that would fix the issue but brings in another.
when upside down the suspension force is now pointing in the wrong direction.
now you may say âthats an easy fix just point that force to the up vector of the carâ and no that wouldnt work since now we are back to where we started with the vector force being relative to attachment0 but with more steps
Exactly.
I actually have no idea how this is calculated internally. Additionally, we do not know exactly how much force is being applied. However, what I did in a similar situation (more of a hacky workaround) is to allow the suspension force to be negative to some extent (although this may be problematic). You can also get a rough calculation using AssemblyAngularVelocity
if that works better for you.