-[[ MOVEMENT + DASH SYSTEM (with Mobile support and "John Doe" style intro) ----------------------------------------------------------------- Where to place it: StarterPlayer > StarterPlayerScripts (as a LocalScript) - Keeps all the original sprint/dash/animation logic. - Automatically detects if the player is on mobile (touch). - On mobile, shows an intro in black/yellow with a "scanline" and glitch effect, then reveals two buttons: [R] sprint and [Q] dash. - On PC it keeps working normally via keyboard (R and Q). ]] local Players = game:GetService("Players") local UserInputService = game:GetService("UserInputService") local RunService = game:GetService("RunService") local TweenService = game:GetService("TweenService") local SoundService = game:GetService("SoundService") local player = Players.LocalPlayer local playerGui = player:WaitForChild("PlayerGui") -- ===================== CONFIG ===================== local HIT_SOUND_ID = "rbxassetid://138651783706047" local DASH_ANIM_ID = "rbxassetid://73053491533472" local DASH_DURATION = 0.6 local DASH_SPEED = 85 local DELAY_BEFORE_DASH = 0.5 local DASH_HITBOX_RADIUS = 6 local THEME = { Background = Color3.fromRGB(5, 5, 5), Accent = Color3.fromRGB(255, 214, 10), AccentDim = Color3.fromRGB(120, 100, 0), Stroke = Color3.fromRGB(40, 36, 0), } local isSprinting = false local character, humanoid, rootPart, animator local idleTrack, forwardTrack, backwardTrack, sprintTrack, currentTrack, dashTrack local heartbeatConn, speedLoopTask, dashHitConnection local isDashing = false local hitDebounce = {} local originalCollisionGroup -- Keep as true while testing on PC/Studio to force the mobile GUI -- to appear even without touch. Set to false when publishing the game. local FORCE_MOBILE_UI_FOR_TESTING = true local isMobile = FORCE_MOBILE_UI_FOR_TESTING or (UserInputService.TouchEnabled and not UserInputService.KeyboardEnabled) -- ===================== MOVEMENT LOGIC (original base) ===================== local function onHitDuringDash(hitCharacter) if not isDashing then return end if hitDebounce[hitCharacter] then return end hitDebounce[hitCharacter] = true local hitSound = Instance.new("Sound") hitSound.SoundId = HIT_SOUND_ID hitSound.Volume = 0.7 hitSound.Pitch = 1 hitSound.Parent = SoundService hitSound:Play() hitSound.Ended:Connect(function() hitSound:Destroy() end) task.delay(0.8, function() hitDebounce[hitCharacter] = nil end) end local function stopTrack(track, fadeTime) if track and track.IsPlaying then track:Stop(fadeTime or 0.1) end end local function playOnly(track, speedOverride) if not track then return end if currentTrack == track then if not track.IsPlaying then track:Play(0.1) end if speedOverride then track:AdjustSpeed(speedOverride) end return end if currentTrack then currentTrack:Stop(0.1) end currentTrack = track track:Play(0.1, 1, speedOverride or 1) end local function makeTrack(id, priority, looped) local anim = Instance.new("Animation") anim.AnimationId = id local track = animator:LoadAnimation(anim) track.Priority = priority track.Looped = looped or false return track end local function cleanup() if heartbeatConn then heartbeatConn:Disconnect() end if dashHitConnection then dashHitConnection:Disconnect() end stopTrack(idleTrack) stopTrack(forwardTrack) stopTrack(backwardTrack) stopTrack(sprintTrack) stopTrack(dashTrack) hitDebounce = {} if character and originalCollisionGroup then for _, part in ipairs(character:GetDescendants()) do if part:IsA("BasePart") then part.CollisionGroup = originalCollisionGroup part.CanCollide = true end end end end local function applyWalkSpeed() if not humanoid then return end local md = humanoid.MoveDirection local moving = md.Magnitude > 0.1 if not moving then humanoid.WalkSpeed = isSprinting and 24 or 8 return end local dot = md:Dot(rootPart.CFrame.LookVector) humanoid.WalkSpeed = (dot < -0.2) and 6 or (isSprinting and 24 or 8) end local function updateAnimations() if not humanoid or not rootPart then return end local md = humanoid.MoveDirection local moving = md.Magnitude > 0.1 if not moving then playOnly(idleTrack) elseif md:Dot(rootPart.CFrame.LookVector) < -0.2 then playOnly(backwardTrack) elseif isSprinting then playOnly(sprintTrack, 2.5) else playOnly(forwardTrack) end end -- ===== Reusable actions (called by both keyboard AND mobile buttons) ===== local function toggleSprint() if isDashing then return end isSprinting = not isSprinting applyWalkSpeed() updateAnimations() end local function dash() if not character or not rootPart or not humanoid or isDashing then return end isDashing = true isSprinting = false hitDebounce = {} originalCollisionGroup = rootPart.CollisionGroup for _, part in ipairs(character:GetDescendants()) do if part:IsA("BasePart") then part.CollisionGroup = "Default" part.CanCollide = false end end if animator then local anim = Instance.new("Animation") anim.AnimationId = DASH_ANIM_ID dashTrack = animator:LoadAnimation(anim) dashTrack.Priority = Enum.AnimationPriority.Action3 dashTrack.Looped = false dashTrack:Play() end task.wait(DELAY_BEFORE_DASH) if not rootPart or not rootPart.Parent then isDashing = false return end humanoid.AutoRotate = false local forwardDir = rootPart.CFrame.LookVector local currentVel = rootPart.AssemblyLinearVelocity local dashTween = TweenService:Create(rootPart, TweenInfo.new(DASH_DURATION, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out), { AssemblyLinearVelocity = forwardDir * DASH_SPEED + Vector3.new(0, currentVel.Y, 0) }) dashTween:Play() dashTween.Completed:Connect(function() humanoid.AutoRotate = true isDashing = false end) task.delay(DASH_DURATION + 0.5, function() isDashing = false humanoid.AutoRotate = true end) end local function setupDashHitDetection() if dashHitConnection then dashHitConnection:Disconnect() end dashHitConnection = RunService.Heartbeat:Connect(function() if not isDashing or not rootPart then return end local rootPos = rootPart.Position local parts = workspace:GetPartBoundsInRadius(rootPos, DASH_HITBOX_RADIUS) for _, part in ipairs(parts) do local hitChar = part.Parent if hitChar and hitChar:FindFirstChild("Humanoid") and hitChar ~= character then onHitDuringDash(hitChar) end end end) end local function setupCharacter(char) cleanup() character = char task.wait(0.3) humanoid = character:WaitForChild("Humanoid", 5) rootPart = character:WaitForChild("HumanoidRootPart", 5) if not humanoid or not rootPart then return end animator = humanoid:FindFirstChildOfClass("Animator") or Instance.new("Animator", humanoid) local animate = character:FindFirstChild("Animate") if animate then animate.Enabled = false end idleTrack = makeTrack("rbxassetid://111792319821341", Enum.AnimationPriority.Action, true) forwardTrack = makeTrack("rbxassetid://138795419712161", Enum.AnimationPriority.Action, true) backwardTrack = makeTrack("rbxassetid://95970874156673", Enum.AnimationPriority.Action, true) sprintTrack = makeTrack("rbxassetid://94467125495426", Enum.AnimationPriority.Action4, true) applyWalkSpeed() updateAnimations() setupDashHitDetection() speedLoopTask = task.spawn(function() while character and character.Parent do applyWalkSpeed() task.wait(0.1) end end) heartbeatConn = RunService.Heartbeat:Connect(function() if isSprinting and sprintTrack and sprintTrack.IsPlaying then sprintTrack:AdjustSpeed(2.5) end updateAnimations() end) end -- ===================== KEYBOARD (PC) ===================== UserInputService.InputBegan:Connect(function(input, gp) if gp then return end if input.KeyCode == Enum.KeyCode.R then toggleSprint() elseif input.KeyCode == Enum.KeyCode.Q then dash() end end) -- ===================== MOBILE GUI (black/yellow, "hacker" style) ===================== local function createStroke(parent, thickness, color) local stroke = Instance.new("UIStroke") stroke.Thickness = thickness or 1 stroke.Color = color or THEME.Stroke stroke.Parent = parent return stroke end local function createCorner(parent, radius) local corner = Instance.new("UICorner") corner.CornerRadius = UDim.new(0, radius or 12) corner.Parent = parent return corner end -- ---------- Intro (black screen, yellow text, scanline + glitch) ---------- local function playIntro(onFinished) local introGui = Instance.new("ScreenGui") introGui.Name = "IntroGui" introGui.ResetOnSpawn = false introGui.IgnoreGuiInset = true introGui.DisplayOrder = 100 introGui.Parent = playerGui local bg = Instance.new("Frame") bg.Size = UDim2.fromScale(1, 1) bg.BackgroundColor3 = THEME.Background bg.BackgroundTransparency = 1 bg.BorderSizePixel = 0 bg.Parent = introGui local scan = Instance.new("Frame") scan.Size = UDim2.new(1, 0, 0, 2) scan.BackgroundColor3 = THEME.Accent scan.BackgroundTransparency = 0.4 scan.BorderSizePixel = 0 scan.Position = UDim2.new(0, 0, 0, -10) scan.ZIndex = 5 scan.Parent = bg local title = Instance.new("TextLabel") title.Size = UDim2.new(0.9, 0, 0.15, 0) title.Position = UDim2.new(0.05, 0, 0.42, 0) title.BackgroundTransparency = 1 title.Font = Enum.Font.Code title.Text = "SYSTEM INITIALIZING" title.TextColor3 = THEME.Accent title.TextTransparency = 1 title.TextScaled = true title.TextStrokeTransparency = 0.6 title.TextStrokeColor3 = Color3.new(0, 0, 0) title.Parent = bg local subtitle = Instance.new("TextLabel") subtitle.Size = UDim2.new(0.9, 0, 0.06, 0) subtitle.Position = UDim2.new(0.05, 0, 0.58, 0) subtitle.BackgroundTransparency = 1 subtitle.Font = Enum.Font.Code subtitle.Text = "loading controls..." subtitle.TextColor3 = THEME.AccentDim subtitle.TextTransparency = 1 subtitle.TextScaled = true subtitle.Parent = bg TweenService:Create(bg, TweenInfo.new(0.5, Enum.EasingStyle.Sine), {BackgroundTransparency = 0.05}):Play() TweenService:Create(title, TweenInfo.new(0.6, Enum.EasingStyle.Sine), {TextTransparency = 0}):Play() TweenService:Create(subtitle, TweenInfo.new(0.6, Enum.EasingStyle.Sine), {TextTransparency = 0.2}):Play() -- scanline moving down repeatedly task.spawn(function() for _ = 1, 3 do scan.Position = UDim2.new(0, 0, 0, -10) TweenService:Create(scan, TweenInfo.new(1, Enum.EasingStyle.Linear), {Position = UDim2.new(0, 0, 1, 10)}):Play() task.wait(1) end end) -- slight flicker on the title (glitch effect) task.spawn(function() for _ = 1, 6 do task.wait(math.random(15, 30) / 100) title.TextTransparency = (math.random(0, 100) < 15) and 0.5 or 0 end end) task.wait(2.4) local fadeOut = TweenService:Create(bg, TweenInfo.new(0.6, Enum.EasingStyle.Quad), {BackgroundTransparency = 1}) TweenService:Create(title, TweenInfo.new(0.4, Enum.EasingStyle.Quad), {TextTransparency = 1}):Play() TweenService:Create(subtitle, TweenInfo.new(0.4, Enum.EasingStyle.Quad), {TextTransparency = 1}):Play() fadeOut:Play() fadeOut.Completed:Connect(function() introGui:Destroy() if onFinished then onFinished() end end) end -- ---------- Fake CAPTCHA ("prove you're not a bot") ---------- local CAPTCHA_CHARS = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789" -- no ambiguous chars (I, O, 0, 1) local function generateCaptchaCode(length) length = length or 5 local code = "" for _ = 1, length do local index = math.random(1, #CAPTCHA_CHARS) code = code .. CAPTCHA_CHARS:sub(index, index) end return code end local function showCaptcha(onFinished) local captchaGui = Instance.new("ScreenGui") captchaGui.Name = "CaptchaGui" captchaGui.ResetOnSpawn = false captchaGui.IgnoreGuiInset = true captchaGui.DisplayOrder = 95 captchaGui.Parent = playerGui local overlay = Instance.new("Frame") overlay.Size = UDim2.fromScale(1, 1) overlay.BackgroundColor3 = THEME.Background overlay.BackgroundTransparency = 1 overlay.BorderSizePixel = 0 overlay.Parent = captchaGui local panel = Instance.new("Frame") panel.Size = UDim2.fromOffset(380, 280) panel.AnchorPoint = Vector2.new(0.5, 0.5) panel.Position = UDim2.fromScale(0.5, 0.5) panel.BackgroundColor3 = THEME.Background panel.BackgroundTransparency = 1 panel.BorderSizePixel = 0 panel.Parent = overlay createCorner(panel, 14) local panelStroke = createStroke(panel, 2, THEME.Accent) panelStroke.Transparency = 1 local titleLabel = Instance.new("TextLabel") titleLabel.Size = UDim2.new(1, -30, 0, 32) titleLabel.Position = UDim2.new(0, 15, 0, 15) titleLabel.BackgroundTransparency = 1 titleLabel.Font = Enum.Font.Code titleLabel.Text = "VERIFY YOU ARE NOT A BOT" titleLabel.TextColor3 = THEME.Accent titleLabel.TextTransparency = 1 titleLabel.TextScaled = true titleLabel.Parent = panel -- code display area local codeHolder = Instance.new("Frame") codeHolder.Size = UDim2.new(1, -30, 0, 60) codeHolder.Position = UDim2.new(0, 15, 0, 60) codeHolder.BackgroundColor3 = Color3.fromRGB(15, 15, 15) codeHolder.BackgroundTransparency = 1 codeHolder.Parent = panel createCorner(codeHolder, 8) local codeStroke = createStroke(codeHolder, 1, THEME.AccentDim) codeStroke.Transparency = 1 local codeLayout = Instance.new("UIListLayout") codeLayout.FillDirection = Enum.FillDirection.Horizontal codeLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center codeLayout.VerticalAlignment = Enum.VerticalAlignment.Center codeLayout.Padding = UDim.new(0, 6) codeLayout.Parent = codeHolder local currentCode = "" local codeLabels = {} -- draws the distorted code (random tilt per character, like a real captcha) local function renderCode() for _, lbl in ipairs(codeLabels) do lbl:Destroy() end codeLabels = {} currentCode = generateCaptchaCode(5) for i = 1, #currentCode do local ch = currentCode:sub(i, i) local lbl = Instance.new("TextLabel") lbl.Size = UDim2.fromOffset(36, 44) lbl.BackgroundTransparency = 1 lbl.Font = Enum.Font.Code lbl.Text = ch lbl.TextScaled = true lbl.TextColor3 = THEME.Accent lbl.Rotation = math.random(-12, 12) lbl.Parent = codeHolder table.insert(codeLabels, lbl) end end renderCode() local inputBox = Instance.new("TextBox") inputBox.Size = UDim2.new(1, -30, 0, 40) inputBox.Position = UDim2.new(0, 15, 0, 135) inputBox.BackgroundColor3 = Color3.fromRGB(10, 10, 10) inputBox.BackgroundTransparency = 1 inputBox.PlaceholderText = "Type the code above" inputBox.PlaceholderColor3 = THEME.AccentDim inputBox.Text = "" inputBox.Font = Enum.Font.Code inputBox.TextScaled = true inputBox.TextColor3 = THEME.Accent inputBox.ClearTextOnFocus = false inputBox.Parent = panel createCorner(inputBox, 8) local inputStroke = createStroke(inputBox, 1.5, THEME.AccentDim) inputStroke.Transparency = 1 local errorLabel = Instance.new("TextLabel") errorLabel.Size = UDim2.new(1, -30, 0, 20) errorLabel.Position = UDim2.new(0, 15, 0, 180) errorLabel.BackgroundTransparency = 1 errorLabel.Font = Enum.Font.Code errorLabel.Text = "Incorrect code, try again." errorLabel.TextColor3 = Color3.fromRGB(255, 90, 90) errorLabel.TextTransparency = 1 errorLabel.TextScaled = true errorLabel.Parent = panel local verifyButton = Instance.new("TextButton") verifyButton.Size = UDim2.fromOffset(140, 40) verifyButton.AnchorPoint = Vector2.new(0.5, 1) verifyButton.Position = UDim2.new(0.5, 0, 1, -15) verifyButton.BackgroundColor3 = THEME.Background verifyButton.BackgroundTransparency = 1 verifyButton.Text = "VERIFY" verifyButton.Font = Enum.Font.Code verifyButton.TextScaled = true verifyButton.TextColor3 = THEME.Accent verifyButton.TextTransparency = 1 verifyButton.AutoButtonColor = false verifyButton.Parent = panel createCorner(verifyButton, 8) local verifyStroke = createStroke(verifyButton, 2, THEME.Accent) verifyStroke.Transparency = 1 -- fade in everything TweenService:Create(overlay, TweenInfo.new(0.4), {BackgroundTransparency = 0.35}):Play() TweenService:Create(panel, TweenInfo.new(0.4), {BackgroundTransparency = 0.1}):Play() TweenService:Create(panelStroke, TweenInfo.new(0.4), {Transparency = 0}):Play() TweenService:Create(titleLabel, TweenInfo.new(0.4), {TextTransparency = 0}):Play() TweenService:Create(codeHolder, TweenInfo.new(0.4), {BackgroundTransparency = 0.2}):Play() TweenService:Create(codeStroke, TweenInfo.new(0.4), {Transparency = 0.2}):Play() TweenService:Create(inputBox, TweenInfo.new(0.4), {BackgroundTransparency = 0.15}):Play() TweenService:Create(inputStroke, TweenInfo.new(0.4), {Transparency = 0.2}):Play() TweenService:Create(verifyButton, TweenInfo.new(0.4), {BackgroundTransparency = 0.2, TextTransparency = 0}):Play() TweenService:Create(verifyStroke, TweenInfo.new(0.4), {Transparency = 0}):Play() -- shake effect when the code is wrong local function shakePanel() local originalPos = panel.Position task.spawn(function() for _, offset in ipairs({-12, 10, -8, 6, 0}) do TweenService:Create(panel, TweenInfo.new(0.06, Enum.EasingStyle.Linear), { Position = originalPos + UDim2.fromOffset(offset, 0) }):Play() task.wait(0.06) end end) end local function closeCaptcha() local fade = TweenService:Create(overlay, TweenInfo.new(0.35), {BackgroundTransparency = 1}) TweenService:Create(panel, TweenInfo.new(0.35), {BackgroundTransparency = 1}):Play() TweenService:Create(panelStroke, TweenInfo.new(0.35), {Transparency = 1}):Play() TweenService:Create(titleLabel, TweenInfo.new(0.35), {TextTransparency = 1}):Play() TweenService:Create(codeHolder, TweenInfo.new(0.35), {BackgroundTransparency = 1}):Play() TweenService:Create(codeStroke, TweenInfo.new(0.35), {Transparency = 1}):Play() TweenService:Create(inputBox, TweenInfo.new(0.35), {BackgroundTransparency = 1}):Play() TweenService:Create(inputStroke, TweenInfo.new(0.35), {Transparency = 1}):Play() TweenService:Create(verifyButton, TweenInfo.new(0.35), {BackgroundTransparency = 1, TextTransparency = 1}):Play() TweenService:Create(verifyStroke, TweenInfo.new(0.35), {Transparency = 1}):Play() for _, lbl in ipairs(codeLabels) do TweenService:Create(lbl, TweenInfo.new(0.35), {TextTransparency = 1}):Play() end fade:Play() fade.Completed:Connect(function() captchaGui:Destroy() if onFinished then onFinished() end end) end local function attemptVerify() local typed = inputBox.Text:upper():gsub("%s", "") if typed == currentCode then closeCaptcha() else shakePanel() inputBox.Text = "" errorLabel.TextTransparency = 0 task.delay(1.5, function() if errorLabel.Parent then TweenService:Create(errorLabel, TweenInfo.new(0.3), {TextTransparency = 1}):Play() end end) renderCode() end end verifyButton.MouseButton1Click:Connect(attemptVerify) inputBox.FocusLost:Connect(function(enterPressed) if enterPressed then attemptVerify() end end) end -- ---------- Mobile buttons ---------- local function createMobileButton(name, text, position) local button = Instance.new("TextButton") button.Name = name button.Size = UDim2.fromOffset(80, 80) button.Position = position button.AnchorPoint = Vector2.new(0.5, 0.5) button.BackgroundColor3 = THEME.Background button.BackgroundTransparency = 0.25 button.Text = text button.Font = Enum.Font.Code button.TextScaled = true button.TextColor3 = THEME.Accent button.AutoButtonColor = false createCorner(button, 40) local stroke = createStroke(button, 2, THEME.Accent) button.MouseButton1Down:Connect(function() TweenService:Create(button, TweenInfo.new(0.1), {BackgroundTransparency = 0}):Play() TweenService:Create(stroke, TweenInfo.new(0.1), {Thickness = 4}):Play() end) button.MouseButton1Up:Connect(function() TweenService:Create(button, TweenInfo.new(0.15), {BackgroundTransparency = 0.25}):Play() TweenService:Create(stroke, TweenInfo.new(0.15), {Thickness = 2}):Play() end) return button end -- Pulsing yellow halo behind the button (glow effect) local function createGlow(button) local glow = Instance.new("Frame") glow.Name = "Glow" glow.AnchorPoint = Vector2.new(0.5, 0.5) glow.Position = UDim2.fromScale(0.5, 0.5) glow.Size = UDim2.fromOffset(button.Size.X.Offset + 20, button.Size.Y.Offset + 20) glow.BackgroundColor3 = THEME.Accent glow.BackgroundTransparency = 0.85 glow.ZIndex = button.ZIndex - 1 glow.Parent = button createCorner(glow, 999) task.spawn(function() while glow.Parent do local grow = TweenService:Create(glow, TweenInfo.new(1.1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), { BackgroundTransparency = 0.55, Size = UDim2.fromOffset(button.Size.X.Offset + 45, button.Size.Y.Offset + 45), }) grow:Play() grow.Completed:Wait() if not glow.Parent then break end local shrink = TweenService:Create(glow, TweenInfo.new(1.1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), { BackgroundTransparency = 0.85, Size = UDim2.fromOffset(button.Size.X.Offset + 20, button.Size.Y.Offset + 20), }) shrink:Play() shrink.Completed:Wait() end end) return glow end -- "Floating" effect (smoothly moves up and down) local function applyFloatingEffect(guiObject, amplitude, duration) amplitude = amplitude or 6 duration = duration or 1.5 task.spawn(function() while guiObject.Parent do local basePos = guiObject.Position local up = TweenService:Create(guiObject, TweenInfo.new(duration, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), { Position = basePos - UDim2.fromOffset(0, amplitude) }) up:Play() up.Completed:Wait() if not guiObject.Parent then break end local down = TweenService:Create(guiObject, TweenInfo.new(duration, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), { Position = basePos }) down:Play() down.Completed:Wait() end end) end -- ---------- Explanatory menu (PC + Mobile) ---------- local function showControlsMenu(onFinished) local menuGui = Instance.new("ScreenGui") menuGui.Name = "ControlsMenu" menuGui.ResetOnSpawn = false menuGui.IgnoreGuiInset = true menuGui.DisplayOrder = 90 menuGui.Parent = playerGui local overlay = Instance.new("Frame") overlay.Size = UDim2.fromScale(1, 1) overlay.BackgroundColor3 = THEME.Background overlay.BackgroundTransparency = 1 overlay.BorderSizePixel = 0 overlay.Parent = menuGui local panel = Instance.new("Frame") panel.Size = UDim2.fromOffset(420, 260) panel.AnchorPoint = Vector2.new(0.5, 0.5) panel.Position = UDim2.fromScale(0.5, 0.55) panel.BackgroundColor3 = THEME.Background panel.BackgroundTransparency = 1 panel.BorderSizePixel = 0 panel.Parent = overlay createCorner(panel, 14) local panelStroke = createStroke(panel, 2, THEME.Accent) panelStroke.Transparency = 1 local titleLabel = Instance.new("TextLabel") titleLabel.Size = UDim2.new(1, -30, 0, 40) titleLabel.Position = UDim2.new(0, 15, 0, 15) titleLabel.BackgroundTransparency = 1 titleLabel.Font = Enum.Font.Code titleLabel.Text = "COMPATIBLE: PC + MOBILE" titleLabel.TextColor3 = THEME.Accent titleLabel.TextTransparency = 1 titleLabel.TextScaled = true titleLabel.Parent = panel local bodyLabel = Instance.new("TextLabel") bodyLabel.Size = UDim2.new(1, -30, 0, 130) bodyLabel.Position = UDim2.new(0, 15, 0, 65) bodyLabel.BackgroundTransparency = 1 bodyLabel.Font = Enum.Font.Code bodyLabel.TextColor3 = THEME.AccentDim bodyLabel.TextTransparency = 1 bodyLabel.TextWrapped = true bodyLabel.TextXAlignment = Enum.TextXAlignment.Left bodyLabel.TextYAlignment = Enum.TextYAlignment.Top bodyLabel.TextSize = 18 bodyLabel.Text = "> On PC: press [R] to sprint and [Q] to dash.\n\n> On Mobile: use the floating buttons on screen for the same actions." bodyLabel.Parent = panel local okButton = Instance.new("TextButton") okButton.Size = UDim2.fromOffset(140, 40) okButton.AnchorPoint = Vector2.new(0.5, 1) okButton.Position = UDim2.new(0.5, 0, 1, -15) okButton.BackgroundColor3 = THEME.Background okButton.BackgroundTransparency = 1 okButton.Text = "GOT IT" okButton.Font = Enum.Font.Code okButton.TextScaled = true okButton.TextColor3 = THEME.Accent okButton.TextTransparency = 1 okButton.AutoButtonColor = false okButton.Parent = panel createCorner(okButton, 8) local okStroke = createStroke(okButton, 2, THEME.Accent) okStroke.Transparency = 1 -- fade in everything TweenService:Create(overlay, TweenInfo.new(0.4), {BackgroundTransparency = 0.35}):Play() TweenService:Create(panel, TweenInfo.new(0.4), {BackgroundTransparency = 0.1}):Play() TweenService:Create(panelStroke, TweenInfo.new(0.4), {Transparency = 0}):Play() TweenService:Create(titleLabel, TweenInfo.new(0.4), {TextTransparency = 0}):Play() TweenService:Create(bodyLabel, TweenInfo.new(0.4), {TextTransparency = 0.1}):Play() TweenService:Create(okButton, TweenInfo.new(0.4), {BackgroundTransparency = 0.2}):Play() TweenService:Create(okStroke, TweenInfo.new(0.4), {Transparency = 0}):Play() TweenService:Create(okButton, TweenInfo.new(0.4), {TextTransparency = 0}):Play() local function closeMenu() local fade = TweenService:Create(overlay, TweenInfo.new(0.35), {BackgroundTransparency = 1}) TweenService:Create(panel, TweenInfo.new(0.35), {BackgroundTransparency = 1}):Play() TweenService:Create(panelStroke, TweenInfo.new(0.35), {Transparency = 1}):Play() TweenService:Create(titleLabel, TweenInfo.new(0.35), {TextTransparency = 1}):Play() TweenService:Create(bodyLabel, TweenInfo.new(0.35), {TextTransparency = 1}):Play() TweenService:Create(okButton, TweenInfo.new(0.35), {BackgroundTransparency = 1, TextTransparency = 1}):Play() TweenService:Create(okStroke, TweenInfo.new(0.35), {Transparency = 1}):Play() fade:Play() fade.Completed:Connect(function() menuGui:Destroy() if onFinished then onFinished() end end) end okButton.MouseButton1Click:Connect(closeMenu) end local function createMobileControls() local gui = Instance.new("ScreenGui") gui.Name = "MobileControls" gui.ResetOnSpawn = false gui.IgnoreGuiInset = true gui.Enabled = false gui.Parent = playerGui local holder = Instance.new("Frame") holder.Name = "Holder" holder.Size = UDim2.fromScale(1, 1) holder.BackgroundTransparency = 1 holder.Parent = gui local sprintButton = createMobileButton("SprintButton", "R", UDim2.new(1, -170, 1, -110)) sprintButton.Parent = holder createGlow(sprintButton) local dashButton = createMobileButton("DashButton", "Q", UDim2.new(1, -80, 1, -110)) dashButton.Parent = holder createGlow(dashButton) for _, btn in ipairs({sprintButton, dashButton}) do local finalPos = btn.Position btn.Position = finalPos + UDim2.fromOffset(0, 120) btn.BackgroundTransparency = 1 local entrance = TweenService:Create(btn, TweenInfo.new(0.4, Enum.EasingStyle.Back, Enum.EasingDirection.Out), { Position = finalPos, BackgroundTransparency = 0.25, }) entrance:Play() entrance.Completed:Connect(function() applyFloatingEffect(btn, 6, 1.4) end) end sprintButton.MouseButton1Click:Connect(toggleSprint) dashButton.MouseButton1Click:Connect(dash) RunService.Heartbeat:Connect(function() sprintButton.TextColor3 = isSprinting and THEME.Accent or THEME.AccentDim end) return gui end -- ===================== INITIALIZATION ===================== player.CharacterAdded:Connect(setupCharacter) player.CharacterRemoving:Connect(cleanup) if player.Character then task.spawn(setupCharacter, player.Character) end if isMobile then playIntro(function() showCaptcha(function() showControlsMenu(function() local mobileGui = createMobileControls() mobileGui.Enabled = true end) end) end) end