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

how would i go about making planet gravity like this game
Smooth Terrain Planet - Roblox
(without the major bugs)

and this First Europa spawn in SSE2, players react - YouTube

i been researching for a few days and everything i find either doesnt have how to make it or not willing to help

egomoose’s gravity does not work i tried


i did the controller for the player and now im looking for help for getting my physics based car to rotate around the planet. this is important and i cant just glue the car to the planet due to it will make it too hard to traverse rough terrain.

the car conversation starts at message 23
(since its still about planet gravity i reused the topic)

1 Like

ok after doing some research heres some more explanation on what i wish to make

picture #1
this is the ideal setup i wish for these planets but i will list different ones that i will use if i have to
we got a planet and a player and a “center” of the planet

we will call the center C. this center is used to tell where the player should be rotated based on its location

so in step 1 no rotation should be applied, the player is right above the center therefore no rotation but in step 2 the player is now further along the planet. therefore a corrected rotation needs to happen (as seen in gray player and red player

picture #2
this is all simple when you got just sphere but now we bring in terrain with hills and mountains
now we got a sphere with some points to it. now heres what separates egomoose’s gravity controller to what i want. in his gravity controller you would rotate to make you in line with the ground. this is not what i want. i want the planet itself to only curve you. so if you were on a hill you shouldnt be rotated to be in line with the hill you should still walk up it like a normal ramp in roblox

as seen in the picture this is shown incorrectly in step 1 and correctly in step 2

option 2
instead of using just a center point for everything i can also do this. you could have a sphere thats just slightly below the surface of the terrain and do the math for the curve of that sphere and only the sphere. this will make it so the hills/mountains issue wont ever happen. but there are a few flaws

  1. if the mountain/hill doesnt curve with the planet; the player will curve faster than the ground causing them to be uneven and maybe even fall off
  2. if going under the part you may be flung depending on how it was set up

option 3
this is the final option im willing to take is no terrain. but still allow the ability to have mountains and hills like in picture 2. if no one can figure out how to make this work with terrain (and i know its possible since other people did it) then im willing to do this option

know i hope people who come along and read this get a better understanding in what im trying to make

3 Likes

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.