I don’t know quite how new you are to scripting, so I’ll assume you understand code but don’t know the specifics.
First things first, you need to get the UserInputService. Easy!
local uis = game:GetService("UserInputService")
This gets all the things the UIS can do for us.
You then need to make it so that it detects when the user has pressed the key desired. Again, this isn’t really all too difficult.
uis.InputBegan:connect(function(input)
if input.KeyCode == Enum.KeyCode.Space then
-- Do something
end
end)
Next up, you’ll need a function for flying that is called whenever your user presses the space bar.
We’ll call this function “Fly”
function fly()
end
This is going to be the bulk of your code, and I’ll write a fairly quick example of how you could write the flying “physics”.
First things first, you need a few variables set up. I’ll lay them all out here:
local myPlayer = game.Players.LocalPlayer
local myChar = myPlayer.Character
local myHRP = myChar:WaitForChild("HumanoidRootPart")
local bp = Instance.new("BodyPosition", myHRP) -- Body Position that determines your location
bp.MaxForce = Vector3.new()
bp.D = 10
bp.P = 10000
local bg = Instance.new("BodyGyro", myHRP) -- Body Gyro that determines your rotation
bg.MaxTorque = Vector3.new()
bg.D = 10
local flying = false -- Determines if you're in flight or not
local rs = game:GetService("RunService") -- Look me up
local camera = game.Workspace.CurrentCamera
local speed = 0.5 -- Speed of flight is kind of determined by this
And now the function can be written:
function fly()
flying = true
bp.MaxForce = Vector3.new(400000,400000,400000)
bg.MaxTorque = Vector3.new(400000,400000,400000)
while flying do
rs.RenderStepped:wait()
bp.Position = myHRP.Position +((myHRP.Position - camera.CFrame.p).unit * speed)
bg.CFrame = CFrame.new(camera.CFrame.p, myHRP.Position)
end
end
But this will force you to fly forever. You’ll need another function that lets you stop the person from flying. I’ll wrap up everything together now!
The end code looks a lil’ like this:
local uis = game:GetService("UserInputService")
local rs = game:GetService("RunService")
local myPlayer = game.Players.LocalPlayer
local myChar = myPlayer.Character
local myHRP = myChar:WaitForChild("HumanoidRootPart")
local camera = game.Workspace.CurrentCamera
local flying = false
local speed = 0.5
local bp = Instance.new("BodyPosition", myHRP)
bp.MaxForce = Vector3.new()
bp.D = 10
bp.P = 10000
local bg = Instance.new("BodyGyro", myHRP)
bg.MaxTorque = Vector3.new()
bg.D = 10
function fly()
flying = true
bp.MaxForce = Vector3.new(400000,400000,400000)
bg.MaxTorque = Vector3.new(400000,400000,400000)
while flying do
rs.RenderStepped:wait()
bp.Position = myHRP.Position +((myHRP.Position - camera.CFrame.p).unit * speed)
bg.CFrame = CFrame.new(camera.CFrame.p, myHRP.Position)
end
end
function endFlying()
bp.MaxForce = Vector3.new()
bg.MaxTorque = Vector3.new()
flying = false
end
uis.InputBegan:connect(function(input)
if input.KeyCode == Enum.KeyCode.Space then
if not flying then
fly()
else
endFlying()
end
end
end)
You wanted to also add in animations, and apparently make it so that if you touch the ground, you stop flying. The former is simple. Look up loading animations into a humanoid and then playing them.
Looks a bit like this:
local hum = char:WaitForChild("Humanoid") --the npc's humanoid
local animation = hum:LoadAnimation(script.Animation) -- Should be an animation object inside the script
animation:Play() --plays the animation
The touching the ground can be done in two ways. You could either set a .Touched event for the HRP which triggers stop flying, or alternatively you could do a continuous raycast check whilst flying. I wouldn’t recommend the latter if you’re worried about performance, though.
I hope this helps