What is the most efficient way of making a part float a fixed amount of studs above ground?

Title says it all. I do NOT want to use BodyVelocity/AlignPosition or anything like that, just plain vector forces. Would also be good if the method did not involve the part’s velocity because it causes bugs with what I’m working with. Any help is appreciated.

Do you want physics to react to it or do you want it floating but anchored?

You can use the Kinetic Energy Formula and F = ma to calculate the force being pushed down.
Kinetic Energy Formula for the current force
and F = ma for gravity.
you can use VectorForce

this should keep it a float from gravity

local mass = workspace.Part.AssemblyMass -- Get total mass of all the connected parts
local forceOfGravity = mass * workspace.Gravity
VectorForce.Force = Vector3.yAxis * forceOfGravity

to make it stop at it’s current speed and stop at gravity you can use kinetic energy formula

local mass = workspace.Part.AssemblyMass -- Get total mass of all the connected parts
local forceOfGravity = mass * workspace.Gravity
local kineticForce = (1/2) * mass * workspace.Part.AssemblyLinearVelocity.Y^2
VectorForce.Force = Vector3.yAxis * (forceOfGravity + kineticForce)
1 Like

You can raycast downwards, check the distance, and adjust to be your fixed amount.

local RaycastModule = {}

-- Constants
local RAYCAST_DISTANCE = 1000

local Params = RaycastParams.new()
Params.FilterDescendantsInstances = {workspace.CurrentCamera}

local function rayCast(origin, direction,passed_Params)
	local raycastParam = passed_Params or Params
	local worldRay = Ray.new(origin, direction.Unit * RAYCAST_DISTANCE)
	local raycastResult = workspace:Raycast(worldRay.Origin, worldRay.Direction * RAYCAST_DISTANCE, raycastParam)

	-- Optional beam visualization
	if raycastResult then
		local size = Vector3.new(0.2, 0.2, (worldRay.Origin - raycastResult.Position).Magnitude-2)
		local cframe = CFrame.lookAt(worldRay.Origin, raycastResult.Position) * CFrame.new(0, 0, -(size.Z/2)-2)
	else
		print("no hit")
	end

	return raycastResult
end

function RaycastModule.rayCastInDirection(origin, direction,passed_Params)
	return rayCast(origin, direction,passed_Params)
end

function RaycastModule.rayCastToPoint(origin, goalPos,passed_Params)
	local direction = goalPos - origin
	return rayCast(origin, direction,passed_Params)
end

function RaycastModule.rayCastToInput(origin, inputObject,passed_Params)
	local Camera = workspace.CurrentCamera
	local worldRay = Camera:ScreenPointToRay(inputObject.Position.X, inputObject.Position.Y)
	return rayCast(origin, worldRay.Direction,passed_Params)
end

return RaycastModule

Using my raycastmodule,

local raycastModule = require(game.ReplicatedStorage.RaycastModule)
local params = RaycastParams.new()
params.FilterDescendantsInstances = {part}

game:GetService("RunService").Heartbeat:Connect(function()
	local ray = raycastModule.raycastInDirection(part.Position, Vector3.new(0,-1,0)*10,params)
	if ray then
		local distance = ray.Distance
		local difference = fixedDistance-distance
		part.Position+=Vector3.new(0,difference,0)
	end
end)

1 Like

Floating but unanchored, something like a hoverboard

Should it move? Or would it be locked in a certain position? And if it can move, can it move on all axis? (X, Y Z) or should it be locked on an axis? Like for example, locked on Y means it can move left and right, but can’t be pushed upwards to the sky