-- [[ Rscripts Risk Notice ]] -- This script is not verified by rscripts.net. Deal with caution. -- -- Stay safe: -- • Never log in on unofficial Roblox sites or lookalike domains. -- • Real Roblox links use roblox.com (check the .com ending). -- • Treat fake Roblox login / "claim reward" pages as phishing. -- [[ End Rscripts Risk Notice ]] local Players = game:GetService("Players") local RunService = game:GetService("RunService") local UserInputService = game:GetService("UserInputService") local LocalPlayer = Players.LocalPlayer local Camera = workspace.CurrentCamera -- Clean up older interface if LocalPlayer.PlayerGui:FindFirstChild("FPE_MobileVR_Final") then LocalPlayer.PlayerGui.FPE_MobileVR_Final:Destroy() end -- Mobile Optimized Interface local ScreenGui = Instance.new("ScreenGui") ScreenGui.Name = "FPE_MobileVR_Final" ScreenGui.Parent = LocalPlayer:WaitForChild("PlayerGui") local ToggleBtn = Instance.new("TextButton") ToggleBtn.Size = UDim2.new(0, 160, 0, 50) ToggleBtn.Position = UDim2.new(0.05, 0, 0.15, 0) ToggleBtn.BackgroundColor3 = Color3.fromRGB(0, 160, 80) ToggleBtn.TextColor3 = Color3.fromRGB(255, 255, 255) ToggleBtn.Text = "VR Override: OFF" ToggleBtn.TextSize = 16 ToggleBtn.Font = Enum.Font.SourceSansBold ToggleBtn.Parent = ScreenGui local BtnCorner = Instance.new("UICorner") BtnCorner.CornerRadius = UDim.new(0, 10) BtnCorner.Parent = ToggleBtn local vrEnabled = false local leftArmCur, rightArmCur = CFrame.new(), CFrame.new() local leftLegCur, rightLegCur = CFrame.new(), CFrame.new() -- Track Last Touch Position for Mobile Look Vector local lastTouchInputPosition = Vector2.new(Camera.ViewportSize.X / 2, Camera.ViewportSize.Y / 2) -- Settings Tuning local armInertia = 0.10 local legInertia = 0.14 local microSpeed = 12 local microAmt = 0.03 local swaySpeed = 2.5 local swayAmt = 0.07 -- R6 Base Joint Offsets local R6_LeftShoulderRest = CFrame.new(-1, 0.5, 0) * CFrame.Angles(0, -math.pi/2, 0) local R6_RightShoulderRest = CFrame.new(1, 0.5, 0) * CFrame.Angles(0, math.pi/2, 0) local R6_LeftHipRest = CFrame.new(-0.5, -1, 0) * CFrame.Angles(0, -math.pi/2, 0) local R6_RightHipRest = CFrame.new(0.5, -1, 0) * CFrame.Angles(0, math.pi/2, 0) -- Capture Screen Touches for Mobile Aiming local function updateTouchLocation(input) if input.UserInputType == Enum.UserInputType.Touch then lastTouchInputPosition = input.Position end end UserInputService.TouchStarted:Connect(updateTouchLocation) UserInputService.TouchMoved:Connect(updateTouchLocation) ToggleBtn.MouseButton1Click:Connect(function() vrEnabled = not vrEnabled local char = LocalPlayer.Character local animateScript = char and char:FindFirstChild("Animate") if vrEnabled then ToggleBtn.Text = "VR Override: ON" ToggleBtn.BackgroundColor3 = Color3.fromRGB(220, 50, 50) if animateScript then animateScript.Disabled = true end if char and char:FindFirstChildOfClass("Humanoid") then for _, track in pairs(char.Humanoid:GetPlayingAnimationTracks()) do track:Stop() end end else ToggleBtn.Text = "VR Override: OFF" ToggleBtn.BackgroundColor3 = Color3.fromRGB(0, 160, 80) if animateScript then animateScript.Disabled = false end if char and char:FindFirstChild("Torso") then local torso = char.Torso if torso:FindFirstChild("Left Shoulder") then torso["Left Shoulder"].C0 = R6_LeftShoulderRest end if torso:FindFirstChild("Right Shoulder") then torso["Right Shoulder"].C0 = R6_RightShoulderRest end if torso:FindFirstChild("Left Hip") then torso["Left Hip"].C0 = R6_LeftHipRest end if torso:FindFirstChild("Right Hip") then torso["Right Hip"].C0 = R6_RightHipRest end end end end) -- Dynamic Flashlight & Teacher Weapon Management local function manageEquippedItems(char) -- 1. Handle Teacher Weapons built into the morph for _, child in pairs(char:GetDescendants()) do if child:IsA("BasePart") and (child.Name:lower():find("compass") or child.Name:lower():find("claw") or child.Name:lower():find("cutter") or child.Name:lower():find("weapon")) then if child.CanCollide then child.CanCollide = false end end end -- 2. Force equipped Flashlights/Tools to update manually alongside our custom R6 joints local tool = char:FindFirstChildOfClass("Tool") if tool and tool:FindFirstChild("Handle") and char:FindFirstChild("Right Arm") then local handle = tool.Handle -- Look for default Roblox RightGrip weld that tends to break without animations active local rightGrip = char["Right Arm"]:FindFirstChild("RightGrip") or handle:FindFirstChild("RightGrip") if rightGrip then -- Clean out default welding properties and force flashlight to lock natively to the moving arm orientation rightGrip.C0 = CFrame.new(0, -1, 0) * CFrame.Angles(math.rad(-90), 0, 0) end end end RunService.RenderStepped:Connect(function() if not vrEnabled then return end local char = LocalPlayer.Character local hum = char and char:FindFirstChildOfClass("Humanoid") local torso = char and char:FindFirstChild("Torso") if not (torso and hum) then return end local leftShoulder = torso:FindFirstChild("Left Shoulder") local rightShoulder = torso:FindFirstChild("Right Shoulder") local leftHip = torso:FindFirstChild("Left Hip") local rightHip = torso:FindFirstChild("Right Hip") if not (leftShoulder and rightShoulder and leftHip and rightHip) then return end -- Keep default animations forced off local animateScript = char:FindFirstChild("Animate") if animateScript and not animateScript.Disabled then animateScript.Disabled = true end -- Fix welding for tools/weapons manageEquippedItems(char) local clock = tick() local isMoving = hum.MoveDirection.Magnitude > 0.1 -- VR Shaking/Tracking simulation logic local trmX = math.sin(clock * microSpeed) * microAmt local trmY = math.cos(clock * (microSpeed * 0.9)) * microAmt local swyX = math.sin(clock * swaySpeed) * swayAmt local swyY = math.cos(clock * (swaySpeed * 1.1)) * swayAmt ----------------------------------------- -- 1. MOBILE TOUCH HAND SYSTEM (Aims Flashlight) ----------------------------------------- local unitRay = Camera:ScreenPointToRay(lastTouchInputPosition.X, lastTouchInputPosition.Y) local pointerWorldTarget = unitRay.Origin + (unitRay.Direction * 6.5) local localTarget = torso.CFrame:ToObjectSpace(CFrame.new(pointerWorldTarget)) local armLeftTgt = CFrame.new(localTarget.Position + Vector3.new(-0.55 + swyX, -0.45 + swyY + trmY, -0.2)) * CFrame.Angles(math.rad(localTarget.Y * 35) + swyY, math.rad(-localTarget.X * 15) + trmX, math.rad(-12)) local armRightTgt = CFrame.new(localTarget.Position + Vector3.new(0.55 + swyY, -0.45 + swyX + trmX, -0.2)) * CFrame.Angles(math.rad(localTarget.Y * 35) + swyX, math.rad(-localTarget.X * 15) + trmY, math.rad(12)) leftArmCur = leftArmCur:Lerp(armLeftTgt, armInertia) rightArmCur = rightArmCur:Lerp(armRightTgt, armInertia) leftShoulder.C0 = leftArmCur rightShoulder.C0 = rightArmCur ----------------------------------------- -- 2. MOBILE WOBBLY LEGS SYSTEM ----------------------------------------- local legLeftTgt, legRightTgt if isMoving then local walkCycle = clock * (hum.WalkSpeed * 0.8) local leftSway = math.sin(walkCycle) local rightSway = math.cos(walkCycle) legLeftTgt = CFrame.new(-0.5 + (leftSway * 0.12), -1 + (math.abs(rightSway) * 0.12), leftSway * 0.25) * CFrame.Angles(leftSway * 0.45, math.rad(-90) + (rightSway * 0.15), leftSway * 0.08) legRightTgt = CFrame.new(0.5 + (rightSway * 0.12), -1 + (math.abs(leftSway) * 0.12), rightSway * 0.25) * CFrame.Angles(rightSway * 0.45, math.rad(90) + (leftSway * 0.15), rightSway * 0.08) else local standWobbleX = math.sin(clock * 1.8) * 0.04 local standWobbleZ = math.cos(clock * 1.3) * 0.03 legLeftTgt = R6_LeftHipRest * CFrame.new(standWobbleX, trmY, standWobbleZ) * CFrame.Angles(standWobbleX, standWobbleZ, trmX) legRightTgt = R6_RightHipRest * CFrame.new(-standWobbleX, trmX, -standWobbleZ) * CFrame.Angles(-standWobbleZ, -standWobbleX, trmY) end leftLegCur = leftLegCur:Lerp(legLeftTgt, legInertia) rightLegCur = rightLegCur:Lerp(legRightTgt, legInertia) leftHip.C0 = leftLegCur rightHip.C0 = rightLegCur end)