Hello!
To begin with, I would like to apologize if the category of this post is not correct. I am not 100% sure if I should place this in Building Support or Scripting Support as it might require both of them.
For the past few days, I was trying to create a levitating platform that you would stand on and it will move depending on which part of the platform is heavier. Here’s an example of what it should look like: Roblox Anakin Vs Obi-Wan (Lava Pad Battle) Roblox Lightsaber Battlegrounds / Roblox Ilum 2 - YouTube
I had some progress with making a part levitate, but it was very buggy (it would not return to its starter rotation/orientation if it is not straight, and when the player stands on it, it would slowly fall down although I’m calculating the players’ weight in the script as well). Also, I’m not really sure how I would make it move depending on where the player stands, would hitboxes work or there is a way to find where the mass is higher?
Here is the script I used. It works, but it doesn’t seem to calculate the player’s mass correctly so when a player stands on the part, the part starts going down slowly or bugs.
game:GetService("RunService").Heartbeat:Connect(function()
local totalMass = totalMass -- Keep a temporary copy of totalMass so it can be modified
local partsCounted = {}
local function check(part)
local human = part.Parent:FindFirstChildOfClass("Humanoid")
if human then
if human:GetLimb(part) ~= Enum.Limb.Unknown then
part = human.RootPart
if check(part) then
partsCounted[part] = true
totalMass = totalMass + part:GetMass()
end
return false
end
end
return not part.Massless and not partsCounted[part] and not script.Parent:IsAncestorOf(part) and not part:IsGrounded()
end
for _, part in ipairs(hitbox:GetTouchingParts()) do
if check(part) then
partsCounted[part] = true
totalMass = totalMass + part:GetMass()
for _, part in ipairs(part:GetConnectedParts(true)) do
if check(part) then
partsCounted[part] = true
totalMass = totalMass + part:GetMass()
end
end
end
end
local ray = Ray.new(thruster.CFrame.p, Vector3.new(0, -1000, 0))
local ignore = {script.Parent}
local hit, pos, norm = workspace:FindPartOnRayWithIgnoreList(ray, ignore)
if not hit then
return
end
while not hit.CanCollide do
table.insert(ignore, hit)
hit, pos, norm = workspace:FindPartOnRayWithIgnoreList(ray, ignore)
if not hit then
return
end
end
local dist = (thruster.CFrame.p-pos).Magnitude-targetHeight.Value
if gyro then
gyro.CFrame = CFrame.new(Vector3.new(), norm)*CFrame.Angles(math.rad(-90), 0, 0)
end
local antiGravity = workspace.Gravity * totalMass/numThrusters
if automaticThrust then
thrust.Value = antiGravity * 2^-stability.Value
end
local forceMask = Vector3.new(0, ((math.abs(dist) <= targetHeight.Value) and 1) or 0, 0)
local thrustForce = thrust.Value - thrust.Value / ((dist/targetHeight.Value)^2)
ThrustForce = math.sign(dist) * math.sign(thrustForce) * math.min(math.abs(thrustForce), thrust.Value*2) -- Make sure force isn't too large
thrustForce = thrustForce + antiGravity -- Add anti gravity force
force.Force = forceMask*thrustForce
thruster.Velocity = thruster.Velocity*damping.Value
end)
You could use this simple hover model, which calculates a force needed to push off the ground with an offset by getting the surface normal to the model itself, you’ll have to do some tweaking yourself, but this for the most part should be a good place to start, maybe? 
https://www.roblox.com/library/1456381316/Simple-Hover