How can i add mobile support to my fly command?

Im wondering how i could add mobile support to this script i am working on

Script:

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local PhysicsService = game:GetService("PhysicsService")

local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local humanoid = character:WaitForChild("Humanoid")
local flying = false
local flyConnection
local moveDirection = Vector3.new(0, 0, 0)

local camera = workspace.CurrentCamera

local function setCollisionGroupRecursive(object, groupName)
	for _, descendant in object:GetDescendants() do
		if descendant:IsA("BasePart") then
			PhysicsService:SetPartCollisionGroup(descendant, groupName)
		end
	end
end

local function toggleFly(commandName, noclip)
	local speed = 50

	if flying then
		flying = false
		if flyConnection then
			flyConnection:Disconnect()
		end
		humanoid.PlatformStand = false
		humanoidRootPart:FindFirstChild("FlyForce"):Destroy()
		humanoidRootPart:FindFirstChild("FlyGyro"):Destroy()
		if noclip then
			setCollisionGroupRecursive(workspace, "Default")
			setCollisionGroupRecursive(character, "Default")
		end
	else
		flying = true
		local flyForce = Instance.new("BodyPosition")
		flyForce.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
		flyForce.Position = humanoidRootPart.Position + Vector3.new(0, 4, 0)
		flyForce.Name = "FlyForce"
		flyForce.Parent = humanoidRootPart

		local bodyGyro = Instance.new("BodyGyro")
		bodyGyro.D = 50
		bodyGyro.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
		bodyGyro.P = noclip and 2000 or 200
		bodyGyro.Name = "FlyGyro"
		bodyGyro.CFrame = humanoidRootPart.CFrame
		bodyGyro.Parent = humanoidRootPart

		local tiltMax = 25
		local tiltAmount = 0
		local tiltInc = 1
		local static = 0

		local look

		if noclip then
			setCollisionGroupRecursive(workspace, "Group1")
			setCollisionGroupRecursive(character, "Group2")
		end

		local lastUpdate = tick()
		local lastPosition = humanoidRootPart.Position

		flyConnection = RunService.RenderStepped:Connect(function()
			local delta = tick() - lastUpdate
			look = (camera.Focus.p - camera.CFrame.p).unit
			local move = CFrame.new(moveDirection * speed * delta)
			local pos = humanoidRootPart.Position
			local targetCFrame = CFrame.new(pos, pos + look) * move
			local targetD = 750 + (speed * 0.2)

			if noclip then
				targetD = targetD / 2
			end

			if move.p ~= Vector3.new() then
				static = 0
				flyForce.D = targetD
				tiltAmount = tiltAmount + tiltInc
				flyForce.Position = targetCFrame.p
			else
				static = static + 1
				tiltAmount = 1
				local maxMag = 6
				local mag = (humanoidRootPart.Position - lastPosition).magnitude
				if mag > maxMag and static >= 4 then
					flyForce.Position = humanoidRootPart.Position
				end
			end

			if math.abs(tiltAmount) > tiltMax then
				tiltAmount = tiltMax
			end

			if flyForce.D == targetD then
				local tiltX = math.clamp(tiltAmount * moveDirection.X * -0.5, -tiltMax, tiltMax)
				local tiltZ = (noclip and 0) or math.clamp(tiltAmount * moveDirection.Z, -tiltMax, tiltMax)
				bodyGyro.CFrame = targetCFrame * CFrame.Angles(math.rad(tiltZ), 0, math.rad(tiltX))
			end

			lastUpdate = tick()
			lastPosition = humanoidRootPart.Position
			humanoid.PlatformStand = true
		end)

		UserInputService.InputBegan:Connect(function(input, gameProcessed)
			if not gameProcessed then
				if input.UserInputType == Enum.UserInputType.Keyboard then
					if input.KeyCode == Enum.KeyCode.W then
						moveDirection = moveDirection + Vector3.new(0, 0, -speed)
					elseif input.KeyCode == Enum.KeyCode.S then
						moveDirection = moveDirection + Vector3.new(0, 0, speed)
					elseif input.KeyCode == Enum.KeyCode.A then
						moveDirection = moveDirection + Vector3.new(-speed, 0, 0)
					elseif input.KeyCode == Enum.KeyCode.D then
						moveDirection = moveDirection + Vector3.new(speed, 0, 0)
					end
				elseif input.UserInputType == Enum.UserInputType.Touch then
					-- Handle touch input for mobile devices
					local touchPosition = input.Position
					local screenCenter = Vector2.new(camera.ViewportSize.X / 2, camera.ViewportSize.Y / 2)
					local direction = Vector2.new(touchPosition.X, touchPosition.Y).Unit
					
					print("Direction:", direction)
					print("Position:", touchPosition)
					print("Center:", screenCenter)
					
					local max_y = 0.5
					local max_x = 0.5
					
					local frame = Instance.new("Frame")

					frame.Parent = player.PlayerGui.GameGui
					frame.Size = UDim2.new(max_x, 0, max_y, 0)
					frame.Position = UDim2.new(0, screenCenter.X, 0, screenCenter.Y)
					
					print(tostring(frame.Position))
					print(tostring(frame.Size))
					
					if touchPosition.X < max_x and touchPosition.Y > max_x then
						moveDirection = Vector3.new(direction.X * speed, 0, direction.Y * speed)
					end
				end
			end
		end)

		UserInputService.InputEnded:Connect(function(input, gameProcessed)
			if input.UserInputType == Enum.UserInputType.Keyboard then
				if input.KeyCode == Enum.KeyCode.W then
					moveDirection = moveDirection - Vector3.new(0, 0, -speed)
				elseif input.KeyCode == Enum.KeyCode.S then
					moveDirection = moveDirection - Vector3.new(0, 0, speed)
				elseif input.KeyCode == Enum.KeyCode.A then
					moveDirection = moveDirection - Vector3.new(-speed, 0, 0)
				elseif input.KeyCode == Enum.KeyCode.D then
					moveDirection = moveDirection - Vector3.new(speed, 0, 0)
				end
			elseif input.UserInputType == Enum.UserInputType.Touch then
				-- Reset move direction when touch ends
				moveDirection = Vector3.new(0, 0, 0)
			end
		end)
	end
end

ReplicatedStorage:WaitForChild("ToggleFly").OnClientEvent:Connect(toggleFly)

1 Like

Somone else recently posted thier fly script which works on mobile alongside gamepad

they utilise the control module’s GetMoveVector method (require(PlayerModule.ControlModule):GetMoveVector()) which gives you a vector describing your movement
This completly removes the need for listening to inputs

2 Likes

How could i implement this? Im still kinda confused on how i use this function.

Change the direction to be relative to the camera looking direction and the move vector and multiply that by the speed that you want

local Speed = 100
(Camera.CFrame.LookVector*-Direction.Z*Speed)+(Camera.CFrame.RightVector*Direction.X*Speed )

just like in the script