Ability on while pressed, off on release

I am not new to programming or modeling, but new to game design, core, and lua. I am trying to create a "while button is pressed" run following code, then "when button is released" run other code.

I am expecting to use this code for things like jet packs, flamethrowers, or pushing/pulling objects. I plan to start with the jetpack. I used a check on the 'IsBindingPressed' function to fire 'set gravity to 0' and 'add impulse vector3.up' which worked - but I cant get the code to run past those commands. My character just floats off into space.

Using the print command shows my script is never getting past "vector3.up." Rather than posting and fixing my code - there has got to be a better way to do this. Does anyone have a working script like this or have any idea?

Below snippet works for me.
Player will fly while "Q" is held down.
Setting gravityScale to 0 didn't work so I used a -2 value.

Good luck

(sorry about the formatting, unsure how to get code to show correctly in the forum)

function OnBindingPressed(whichPlayer, binding)
print("player " .. whichPlayer.name .. " pressed binding: " .. binding)
if (binding == "ability_extra_20") then
whichPlayer.gravityScale = -2
whichPlayer:SetVelocity(Vector3.UP * 100)
end
end
function OnBindingReleased(whichPlayer, binding)
print("player " .. whichPlayer.name .. " released binding: " .. binding)
if (binding == "ability_extra_20") then
whichPlayer.gravityScale = 1.9
end
end
function OnPlayerJoined(player)
-- hook up binding in player joined event here, move to more appropriate place if needed
player.bindingPressedEvent:Connect(OnBindingPressed)
player.bindingReleasedEvent:Connect(OnBindingReleased)
end
-- on player joined/left functions need to be defined before calling event:Connect()
Game.playerJoinedEvent:Connect(OnPlayerJoined)

If a Mod is reading this - the AddImpulse and the Tick() commands need a more robust documentation.

Alright Utterly, that worked! Thank you so much. Now, continuing this jetpack script, if I wanted to start then slowly increase the thrust of the jetpack (incrementally decrease the value of player gravity the longer the binding is held) I assume I would do this with the Tick(deltaTime) command. I am struggling to get it to work. Example posted below:

local thrust = 0.5

function OnBindingPressed(whichPlayer, binding)
print("player " .. whichPlayer.name .. " pressed binding: " .. binding)
if (binding == "ability_extra_20") then
whichPlayer.gravityScale = - thrust
whichPlayer:AddImpulse(Vector3.UP)
function Tick(deltaTime)
local thrust = thrust - 100
end
end
end
function OnBindingReleased(whichPlayer, binding)
print("player " .. whichPlayer.name .. " released binding: " .. binding)
if (binding == "ability_extra_20") then
whichPlayer.gravityScale = 1.9
end
end
function OnPlayerJoined(player)
player.bindingPressedEvent:Connect(OnBindingPressed)
player.bindingReleasedEvent:Connect(OnBindingReleased)
end

Game.playerJoinedEvent:Connect(OnPlayerJoined)

The tick function needs to be outside the onBindingPressed function. I don't think changing the gravityScale will work as you want, I couldn't get the player to fly when I tried it. My attempt below has tick working and player launching into air but the acceleration doesn't seem to increase as expected. Also using vector3.Up doesn't allow the player to fly around only up or down.

Turning on the player flying ability combined with some form of AddImpulse() might work.

There are several Jet Packs in community content so I'd suggest having a look at how those creators have done it and see where that leads you. With scripting I always find it easier to start with something that already does half of what I want and customize it from there.

...........................................................................................
local thrust = 100
local thrustDelta = 100
local isThrusting = false
local targetPlayer = nil

function OnBindingPressed(whichPlayer, binding)
print("player " .. whichPlayer.name .. " pressed binding: " .. binding)
if (binding == "ability_extra_20") then
targetPlayer = whichPlayer
targetPlayer.gravityScale = -2
targetPlayer:SetVelocity(Vector3.UP * thrust)
isThrusting = true
end
end

function Tick(deltaTime)
while isThrusting == true do
thrust = thrust + thrustDelta
targetPlayer:AddImpulse(Vector3.UP * targetPlayer.mass * thrust)
Task.Wait(2)
print("targetPlayer velocity =", targetPlayer:GetVelocity())
end
end

function OnBindingReleased(whichPlayer, binding)
print("player " .. whichPlayer.name .. " released binding: " .. binding)
if (binding == "ability_extra_20") then
whichPlayer.gravityScale = 1.9
isThrusting = false
end
end

function OnPlayerJoined(player)
player.bindingPressedEvent:Connect(OnBindingPressed)
player.bindingReleasedEvent:Connect(OnBindingReleased)
end

Game.playerJoinedEvent:Connect(OnPlayerJoined)
..........................................................................................

Alright, that's super helpful with the tick command, thank you! I was thinking of playing around with the players mass, gravity scale, impulse, and vectors until I get what I am looking for. I think I can affect a single axis (Z specifically) without changing the current velocities of the x and y using math - it would be nice if the core API would let me do this simply. I only found 4 complete jet packs on the community content, only 1 on them actually worked but it was more like an rpg ability than it was a jet pack. Ill keep poking around and seeing what works.