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

Planet gravity can be created using LineForce, VectorForce, or ApplyImpulse. To rotate the character, you must create a custom character system (or somehow manage to rotate the whole map).

well how would that be done. i aint talking about gravity between planets like orbits, i already know how to do that.

im asking how to rotate the character ideally around a single point while still being able to jump and climb mountains and hills

Im sure thats what @SubtotalAnt8185 already replied to you, as the best approach. You should use those LineForce , VectorForce , or ApplyImpulse. To control the character rotation and “attraction force” to the “earth”, and creating a custom Character Controller to handle animations and character behaviour.
OR
rotate whole map for the player, simulating that is walking on a ball

but HOW would that be done. i never done anything like this before and i got no clue how to calculate the forces and rotation

No worries, I was trying to do something very similar to what you are developing right now on my free time… and… Its not working as intended yet ¯_(ツ)_/¯

So… Im not exactly sure how to accomplish it, lets just still trying it until it works!! :yum: :sweat_smile:

Its been done before in unity mimicing games such as super mario galaxy.

The rotation method and unity video is here, I would suggest learning to a point to be able to translate code and studying the advanced CFrame technique:

1 Like

ive converted unity scripts to roblox before for my car scripts

ill try this out later

ok i looked over this and the video and this is what i go so far

but i cant figure out how to make it stay, seems to fall off every time

script:

local planetCenter = workspace.PlanetCenter
local rotationSpeed = 20

local RunService = game:GetService("RunService")

local char = script.Parent
local root = char.HumanoidRootPart

local randomAxis = Vector3.new(1,0,0)

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

local params = RaycastParams.new()
params.FilterDescendantsInstances = {char}
params.FilterType = Enum.RaycastFilterType.Blacklist

local a = Instance.new("Attachment", root)
local force = Instance.new("VectorForce", a)
force.Force = Vector3.new()
force.RelativeTo = Enum.ActuatorRelativeTo.World
force.ApplyAtCenterOfMass = true
force.Attachment0 = a

local gyro = script:WaitForChild("BodyGyro"):Clone()
gyro.Parent = root

local planetGravity = 9.81

local mass = 0
for i, v in pairs(char:GetDescendants()) do
	if v:IsA("BasePart") then
		mass += v:GetMass()
	end
end

RunService.Stepped:Connect(function(dt)
	local result = workspace:Raycast(root.Position, -1000 * root.CFrame.UpVector, params)
	if result then
		local rotateToFloorCFrame = getRotationBetween(root.CFrame.UpVector, result.Normal, randomAxis)
		local goalCF = rotateToFloorCFrame * root.CFrame
		gyro.CFrame = goalCF.Rotation + root.CFrame.Position
		force.Force = -result.Normal * planetGravity * mass
	end
end)

the vector force points to the center of the planet which is just a very small part (which will turn into just a vector3 to save part count)

also when falling off the planet or lets say you were orbiting around it. it doesnt pull you into the planet like it should and i dont know how to do that without increasing the force of the vector force but that will mess up walking around and jumping

The issue is that PlatformStand seems to still be disabled and the movement is using the humanoid movement.

Humanoids will resist the BodyGyro and the moment they tilt 90 degrees it will enter ragdoll mode, therefore it is mandatory to toss humanoids out the window for custom movement especially for tilting as there is no property for that.

You will need an entirely new character controller. In the video below I am using my own PhysicsCharacterController and disabled the auto rotate method

PhysicsCharacterController:RemoveComponent(“AutoRotate”)

However this will require more work as my character controller is basically similar to humanoids only intended for use on the XZ plane with the hipheight raycasting always downwards (0, -1, 0). Consequently, you will need to create a custom AddonComponent or make your own character controller from scratch both methods should work, feel free to make your own if you don’t want to reverse engineer mine.

Also the direction should the the vector towards the center and not necessarily the ray cast which is not want you wanted

This is solved simply using this direction instead:

		local gravityDirection = (planetCenter.Position - root.Position)
RunService.Stepped:Connect(function(dt)
	local result = workspace:Raycast(root.Position, -1000 * root.CFrame.UpVector, params)
	if result then
		local gravityDirection = (planetCenter.Position - root.Position)

		local rotateToFloorCFrame = getRotationBetween(root.CFrame.UpVector, -gravityDirection, randomAxis)
		local goalCF = rotateToFloorCFrame * root.CFrame
		gyro.CFrame = goalCF.Rotation + root.CFrame.Position
		force.Force = gravityDirection.Unit * planetGravity * root.AssemblyMass
	end
end)

does your controller work with r6? and your controller is slides around a lot. is there anyway to fix these issues otherwise ill try to make my own

i want the movement to still feel like a regular humanoid

nvm i modified egomoose’s gravity controller to use the movement from that. but there are a few issues

  1. climbing doesnt work (cant figure out how to make this possible, do you know how?)
  2. when upsde down you cant jump (currently working on a fix) fixed

been working on making my physics based car work with going around the planet
right now im changing the up vector of the suspension force to be the same math as the up vector for the player

this works until it gets to a 90 degree rotation.
im using vector forces and its all simulated so there is a base which is the car and its propelled up (so it doesnt fall) to simulate suspension. i cant figure out how to get the correct up vector so it pushes the car up relative to the planet

suspension force = suspensionForce * self.upVector suspensionForce is a number
this is how i calculate the up vector, this time im actually using the normal of the hit result

local result = workspace:Raycast(data.attach.WorldPosition, -1000 * data.attach.WorldCFrame.UpVector, params)
if result then
	local gravityDir = (planetCenter.Position - data.attach.WorldPosition)
	local rotateToFloorCFrame = getRotationBetween(data.attach.WorldCFrame.UpVector, -result.Normal, Vector3.new(0, 0, 1))

	if gravityDir.Magnitude <= 400 then
		upVector = result.Normal
	else
		upVector = Vector3.new(0, 1, 0)
	end
end
data.wheelController.upVector = upVector

this is what happens

You aren’t showing the code for the vehicle that lifts it up. The raycast is fine.

Though, I wonder what this is for:

thats just for the distance the planet can pull you in for

the code for pushing up is pretty simple is just the dampened spring formula
then setting a vector force to that

i need the vector force to push up while providing enough force in the direction of the planet to keep it on the planet
this can be done through multiple vector forces one for the suspension and one for the gravity force, which is what i did

but the gravity force is way too strong or way too weak and not enough to keep it on the planet

i changed some stuff since that post and this is how i calculate the gravity force

function module:calculateGrav(dt)
	local g = workspace.Gravity
	local mass = self.attach.Parent.AssemblyMass + self.mass
	
	local gForce = g * mass * self.upVector
	return gForce
end

then thats applied to a vector force

local gravForce = data.wheelController:calculateGrav(dt)
data.gravVector.Force = gravForce

currently this force is way too strong and just keeps it stuck on the ground

You can use your own gravity and set Workspace.Gravity to 0

ok so without the suspension force it stays on the planet this time but now with the suspension force it bounces like crazy

right now i get the vertical speed by the base (invisible part where all the vector forces are attached to) with :vectorToWorldSpace() against the upVector or gravity vector that the gravity calculation uses
then i dot that with the velocity at the point of the vector force

this works fine with gravity like the normal one of 196.2 but im using 9.81 since 196.2 is way too strong for the car

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
image
image

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
image

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

causing this
image

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).