How to make the player hover?

scripting

#1

I am trying to make my player hover.
This is part of a game I am doing feasibility study on.
I am not getting the player to hover and don’t know why.
My localscript is

local player = game.Players.LocalPlayer

repeat

wait()

until player.Character:FindFirstChild('UpperTorso')

local pn = player.Name

print(pn)

local activePlayer = workspace:WaitForChild(pn)

local b = Instance.new('BodyForce')

b.Name = "BF"

b.Force = Vector3.new(0,0,0)

b.Parent = activePlayer

local playerMass = 0

for _,obj in pairs(activePlayer:GetDescendants()) do

if obj:IsA('BasePart') then

playerMass = playerMass+obj:GetMass()

end

end

print('playerMass=',playerMass)

local hoverForce = playerMass * 98.2 -- 98.2 is gravity force

activePlayer.BF.Force = Vector3.new(0,hoverForce,0)

activePlayer.PrimaryPart.CFrame = CFrame.new(activePlayer.PrimaryPart.CFrame.X,activePlayer.PrimaryPart.CFrame.Y+1,activePlayer.PrimaryPart.CFrame.Z)

print('hovering?')

#4

You need to use a remote event to do this, fire it to the server then create the force for the player there.


#5

There are two ways that you can do this,
one is via animations. All you have to do is create an animation and animate it so that the HumanoidRootPart is moved slightly upwards, it’ll give your character the “not touching the ground” look. Customize it if needed.

Second, you can also use the Humanoid property “HipHeight”.

https://developer.roblox.com/api-reference/property/Humanoid/HipHeight

The description is also pretty self-explanatory. Your root part y axis will be positioned based on what you set the value as.


#6

You could also play around with Constraints and AlignPosition to achieve a hover effect:


Example Source Code

To be used in a LocalScript:

local hoverHeight = 4
local hoverDelay = 3

local players = game:GetService("Players")
local camera = workspace.CurrentCamera
local player = players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local upperTorso = character:WaitForChild("UpperTorso")
wait(hoverDelay)

local hoverPart = Instance.new("Part")
hoverPart.Anchored = true
hoverPart.CanCollide = false
hoverPart.Transparency = 1
hoverPart.Name = "HoverPart"
hoverPart.Size = Vector3.new(1,1,1)
hoverPart.CFrame = CFrame.new(upperTorso.Position + Vector3.new(0,hoverHeight,0))
hoverPart.Parent = workspace
local hoverAttachment0 = Instance.new("Attachment")
hoverAttachment0.Name = "Attachment0"
hoverAttachment0.Parent = upperTorso
local hoverAttachment1 = Instance.new("Attachment")
hoverAttachment1.Name = "Attachment1"
hoverAttachment1.Parent = hoverPart
local hoverForce = Instance.new("AlignPosition")
hoverForce.Name = "HoverForce"
hoverForce.Attachment0 = hoverAttachment0
hoverForce.Attachment1 = hoverAttachment1
hoverForce.Responsiveness = 10
hoverForce.ApplyAtCenterOfMass = true
hoverForce.Parent = upperTorso
hoverForce.Enabled = true

#7

I tried using HipHeight but it seems to be limited to 100.
I would like to be able to float the character in any direction under the players control as if the player was in space ie zero gravity condition.
My outlined limitation is 900 studs in any direction, apart from below ground
(at this time), starting from the spawn point.


#8

I would suggest BodyVelocity object for a better accessibility. Set MaxForce to math.huge of the direction you want player to stay. Then set Velocity of that axis to 0 to keep player at where it is.

So, let’s say we want player’s position’s Y to stay still, which means hovering.

local BV = Instance.new("BodyVelocity")
BV.MaxForce = Vector3.new(0,math.huge,0)
local YSpeed = 0 --If higher, player will raise. If lower, player will lower.
BV.Velocity = Vector3.new(0,0,0) --Since MaxForce of X and Z is 0, those won't be effected.
BV.Parent = Character.HumanoidRootPart

Please note this code is server-sided. You need to connect this code with a RemoteEvent if you want it client-sided.
If you want hovering to be dependant on a platform, I would still suggest using this method, but with raycasting to the surface and setting velocity accordingly.


#9

When you say ‘hover’ do mean the avatar standing above the ground or an actual floating avatar?


#10

Firstly, thank you for your responses so far. They have all helped me understand a bit more about controlling the character.
Secondly here is my current code.

local player = game.Players.LocalPlayer
local pn = player.Name
print(pn)
local activePlayer = workspace:WaitForChild(pn)
repeat
	wait()
until activePlayer:FindFirstChild("UpperTorso")
local b = Instance.new("BodyForce")
b.Name = "BF"
b.Force = Vector3.new(0,0,0)
b.Parent = activePlayer.PrimaryPart
local playerMass = 0
for _,obj in pairs(activePlayer:GetDescendants()) do
	if obj:IsA("BasePart") then
		playerMass = playerMass+obj:GetMass()
	end
end
print("playerMass=",playerMass)
local hoverForce = playerMass * game.workspace.Gravity
activePlayer.PrimaryPart.BF.Force = Vector3.new(0,hoverForce,0)
local cf = activePlayer:GetPrimaryPartCFrame() * CFrame.new(0,5,0)
activePlayer:SetPrimaryPartCFrame(cf)
print("hovering at 5 studs?")
wait(5)

local speed = 1
local uis = game:GetService("UserInputService")
print("KeyboardReady",uis.KeyboardEnabled)
local qDebounce = false

uis.InputBegan:Connect(function(inst)
	print("key=",inst.KeyCode,"debounce=",qDebounce)
	
    if inst.KeyCode == Enum.KeyCode.Q then
		if qDebounce then 
			return
		else
			qDebounce = true
		end
        print("Q KeyDown")
		cf = activePlayer:GetPrimaryPartCFrame() * CFrame.new(0,speed,0)
		activePlayer:SetPrimaryPartCFrame(cf)
		print("back to hovering")
		qDebounce = false
    end
end)

local zDebounce = false

uis.InputBegan:Connect(function(inst)
	print("key=",inst.KeyCode,"debounce=",zDebounce)

    if inst.KeyCode == Enum.KeyCode.Z then
		if zDebounce then 
			return
		else
			zDebounce = true
		end
        print("Z KeyDown")
		cf = activePlayer:GetPrimaryPartCFrame() * CFrame.new(0,-speed,0)
		activePlayer:SetPrimaryPartCFrame(cf)
		print("back to hovering")
		zDebounce = false
    end
end)

print("press q to go up")
print("press z to go down")

So want to be able to allow the player to move using the normal wasd for horizontal movement as well as introducing qz for vertcial movement q for up, z for down.
This mechanism is a significant part of a number of single player puzzle games I am doing feasibility checks on as well as an enhancement to an existing gaming scenario that I am currently working on.
I am early in my use of roblox and lua but very familiar with coding generally.
i have not thought of code location yet eg client or server.
I am just trying to get an example of a mechanism that works within a local script.
Once that is working I will look into the process of protecting the mechanism so the coding cannot be miss-used.


#11

Ok, so I have a working script which I can use as the basis for what I need in the future but thought I would put a copy here and mark it as a solution to close this discussion and for anyone who wants to do this sort of thing.

local player = game.Players.LocalPlayer
local pn = player.Name
print(pn)
local activePlayer = workspace:WaitForChild(pn)
repeat
	wait()
until activePlayer:FindFirstChild("UpperTorso")
local b = Instance.new("BodyForce")
b.Name = "BF"
b.Force = Vector3.new(0,0,0)
b.Parent = activePlayer.PrimaryPart
local playerMass = 0
for _,obj in pairs(activePlayer:GetDescendants()) do
	if obj:IsA("BasePart") then
		playerMass = playerMass+obj:GetMass()
	end
end
print("playerMass=",playerMass)
local hoverForce = playerMass * game.workspace.Gravity * 0.999972	-- adjusted to get near to hover
print("waiting for player to land")
while activePlayer.PrimaryPart.Position.Y > 3 do
	wait(1)
end
print("applying zero gravity")
local app = activePlayer.PrimaryPart
app.BF.Force = Vector3.new(0,hoverForce,0)
print("applying CFrame upward movement of 5")
local cf = activePlayer:GetPrimaryPartCFrame() * CFrame.new(0,5,0)
activePlayer:SetPrimaryPartCFrame(cf)
print("hovering at 5 studs?")
local ww = 10
while ww > 0 do
	wait(1)
	print("hovering height",activePlayer.PrimaryPart.Position.Y)
	ww = ww -1
end
app.BF.Force = Vector3.new(0,0,0)
local speed = 1
local speedDirection = 0	-- 0 = no movement, 1 = up, -1 = down
local moveCF = CFrame.new(0,speed*speedDirection,0)
local uis = game:GetService("UserInputService")
local rs = game:GetService("RunService")
print("KeyboardReady",uis.KeyboardEnabled)

uis.InputBegan:Connect(function(inst)
	print("key=",inst.KeyCode)
	
    if inst.KeyCode == Enum.KeyCode.Q then
        print("Q KeyDown")
		if app.Position.Y <3 then
			if app.BF.Force.Y == 0 then
				app.BF.Force = Vector3.new(0,hoverForce,0)
			end
		end
		speedDirection = 1
    end
    if inst.KeyCode == Enum.KeyCode.Z then
        print("Z KeyDown")
		if app.Position.Y <5 then
			speedDirection = -0.5
		else
			speedDirection = -1
		end
		if app.Position.Y <3 then
			print("On the ground")
			app.BF.Force = Vector3.new(0,0,0)
			speedDirection = 0
		else
			print("back to hovering")
		end
    end
end)

uis.InputEnded:Connect(function(inst)
	print("key=",inst.KeyCode)

    if inst.KeyCode == Enum.KeyCode.Q then
       print("Q KeyUp")
		speedDirection = 0
   end
   if inst.KeyCode == Enum.KeyCode.Z then
        print("Z KeyUp")
		speedDirection = 0
    end
end)

rs.RenderStepped:connect(function()
  if player.Character then 
	if speedDirection ~= 0 then
		moveCF = CFrame.new(0,speed*speedDirection,0)
	else
		moveCF = CFrame.new(0,0,0)
	end
	cf = activePlayer:GetPrimaryPartCFrame() * moveCF
	activePlayer:SetPrimaryPartCFrame(cf)
	app.Velocity = Vector3.new(app.Velocity.X,speed*speedDirection,app.Velocity.Z)
  end
end)

print("press q to go up")
print("press z to go down")