Hi there, I have this flying script (which was originally written by @EgoMoose in 2018, and then later modified by @FirstVertex in 2021 to add mobile support) and whenever a player dies with it activated it stops working. Using some prints it seems like the script is putting the BodyVelocity and the BodyGyro into the players old HumanoidRootPart and I’m not sure how to stop it from doing it. I’ve tried setting up an event that triggers the setFlying() function whenever the player dies and then redefines the hrp variable, but all redefining the variable does is set it to nil. Below is the flying script and under it is the event I was talking about. Any help is appreciated
I should note that I modified the script to run when a Gui button was pressed. The “Speed” variable used to just be the players walkspeed
local camera = game.Workspace.CurrentCamera;
local player = game.Players.LocalPlayer;
repeat task.wait() until player.Character
local character = player.Character
local hrp = character.HumanoidRootPart
local humanoid = character.Humanoid
local Button = script.Parent
local Speed = script.Parent.Parent.Parent.FlyPopUp.MainBackground.Confirm.Confirm.Speed
while (not character.Parent) do character.AncestryChanged:Wait(); end
local bodyGyro = Instance.new("BodyGyro");
bodyGyro.maxTorque = Vector3.new(1, 1, 1)*10^6;
bodyGyro.P = 10^6;
local bodyVel = Instance.new("BodyVelocity");
bodyVel.maxForce = Vector3.new(1, 1, 1)*10^6;
bodyVel.P = 10^4;
local isFlying = false;
local movement = {forward = 0, backward = 0, right = 0, left = 0};
-- functions
local function setFlying(flying)
isFlying = flying;
bodyGyro.Parent = isFlying and hrp or nil;
bodyVel.Parent = isFlying and hrp or nil;
bodyVel.Velocity = Vector3.new();
if (isFlying) then
bodyGyro.CFrame = hrp.CFrame;
end
end
Button.Activated:Connect(function()
if (not humanoid or humanoid:GetState() == Enum.HumanoidStateType.Dead) then
return;
end
setFlying(not isFlying)
end)
local function onUpdate(dt)
if (isFlying) then
local cf = camera.CFrame;
local direction = cf.rightVector*(movement.right - movement.left) + cf.lookVector*(movement.forward - movement.backward);
if (direction:Dot(direction) > 0) then
direction = direction.unit;
end
bodyGyro.CFrame = cf;
bodyVel.Velocity = direction * Speed.Value * 3;
end
end
local function modifyMovement(newMovement)
movement = newMovement or movement
if (isFlying) then
local isMoving = movement.right + movement.left + movement.forward + movement.backward > 0;
end
-- print('movement modified', movement)
end
local function movementBind(actionName, inputState, inputObject)
if (inputState == Enum.UserInputState.Begin) then
movement[actionName] = 1;
modifyMovement()
elseif (inputState == Enum.UserInputState.End) then
movement[actionName] = 0;
modifyMovement()
end
return Enum.ContextActionResult.Pass;
end
-- UPDATE 8/29/2021
-- THIS PART WAS REMIXED BY @FirstVertex
-- NOW FULLY SUPPORTING MOBILE CONTROLS!
-- See the WormHole for example flight: https://www.roblox.com/games/6665206183
-- STRATEGY: since CAS won't fire movement on mobile while flying, listen for touchmoves
-- on the thumbstick and inquire what's the current movement status from the current
-- controller who's still tracking the movement although it's not broadcasted by CAS
local CAS = game:GetService("ContextActionService");
local UIS = game:GetService("UserInputService");
-- these don't work on mobile while flying
CAS:BindAction("forward", movementBind, false, Enum.PlayerActions.CharacterForward);
CAS:BindAction("backward", movementBind, false, Enum.PlayerActions.CharacterBackward);
CAS:BindAction("left", movementBind, false, Enum.PlayerActions.CharacterLeft);
CAS:BindAction("right", movementBind, false, Enum.PlayerActions.CharacterRight);
-- recursively seek the Control Module and the Touch Control frame
local controller = require(player:FindFirstChild("ControlModule", true))
local touchFrame = player:FindFirstChild('TouchControlFrame', true)
if controller and touchFrame then
local isMovingThumbstick = false
-- tolerance for ignoring small values
local deadZone = 0.15
-- a factor used to normalize inputs between deadZone and 1 to 0-1
local deadZoneNormalized = 1 - deadZone
-- determine if the position is within the current thumbstick's bounds
local function isTouchOnThumbstick(position)
if not touchFrame then return false end
-- "classic" thumbstick
local classicFrame = touchFrame:FindFirstChild('ThumbstickFrame');
-- "dynamic" thumbstick
local dynamicFrame = touchFrame:FindFirstChild('DynamicThumbstickFrame');
local stickFrame = (classicFrame and classicFrame.Visible) and classicFrame or dynamicFrame
if (stickFrame) then
local stickPos = stickFrame.AbsolutePosition
local stickSize = stickFrame.AbsoluteSize
-- is the given position inside the given box
return position.X >= stickPos.X and
position.X <= (stickPos.X + stickSize.X) and
position.Y >= stickPos.Y and
position.Y <= (stickPos.Y + stickSize.Y)
end
return false
end
UIS.TouchStarted:connect(function(touch, gameProcessedEvent)
isMovingThumbstick = isTouchOnThumbstick(touch.Position)
end)
UIS.TouchEnded:connect(function(touch, gameProcessedEvent)
if not isMovingThumbstick then return end
isMovingThumbstick = false
modifyMovement({forward = 0, backward = 0, right = 0, left = 0});
end)
UIS.TouchMoved:connect(function(touch, gameProcessedEvent)
if not isMovingThumbstick then return end
-- although CAS is not firing Enum.PlayerActions.Character* the controller is still tracking the movement, so just ask
local mv = controller:GetMoveVector();
local leftRight = mv.X;
local foreBack = mv.Z;
-- change the range from [0.15-1] to [0-1] if it is outside the deadzone
movement.left = leftRight < -deadZone and -(leftRight-deadZone)/deadZoneNormalized or 0
movement.right = leftRight > deadZone and (leftRight-deadZone)/deadZoneNormalized or 0
movement.forward = foreBack < -deadZone and -(foreBack-deadZone)/deadZoneNormalized or 0
movement.backward = foreBack > deadZone and (foreBack-deadZone)/deadZoneNormalized or 0
modifyMovement()
end)
end
game:GetService("RunService").RenderStepped:Connect(onUpdate)
humanoid.Died:Connect(function()
setFlying(not isFlying)
player.CharacterAdded:Connect(function(NewChar)
hrp = NewChar:FindFirstChild("HumanoidRootPart")
print("hrp redefined", hrp)
end)
end)
-- ^This was added right after the setFlying() was defined