Mobile john doe R15 animation (fixed)
Key RequiredUniversal

Mobile john doe R15 animation (fixed)

Universal ScriptScriptCreatorv8fScriptCreatorv8f 1.3K views 22.2K executesUpdated Sep 6, 2026
Unrated
00
Lua Script•836 lines (27545 chars)
-[[
	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

Features & Information

its just john doe animation
#John Doe#Animation

Community Comments (0)

No comments yet for this script.

More Scripts for Universal Scripts