local ICON_ID = "rbxassetid://127456749272175" local SOUND_ID = "rbxassetid://116615093760278" local TELEPORT_DELAY = 5 local MIN_DISTANCE = 50 -- Minimum studs to teleport away local MAX_DISTANCE = 150 -- Maximum studs to teleport away local Players = game:GetService("Players") local RunService = game:GetService("RunService") local Debris = game:GetService("Debris") local player = Players.LocalPlayer -- UI Setup local screenGui = Instance.new("ScreenGui") screenGui.Name = "EscapeAbilityUI" screenGui.ResetOnSpawn = false screenGui.Parent = player:WaitForChild("PlayerGui") local button = Instance.new("ImageButton") button.Size = UDim2.new(0, 70, 0, 70) button.Position = UDim2.new(0.5, -35, 0.8, -20) button.Image = ICON_ID button.BackgroundColor3 = Color3.fromRGB(0, 0, 0) button.BackgroundTransparency = 0.5 button.Parent = screenGui local corner = Instance.new("UICorner") corner.CornerRadius = UDim.new(1, 0) corner.Parent = button -- Variables local isTeleporting = false local lastHealth = 100 -- Function to find a random valid ground position nearby local function getRandomPosition() local character = player.Character if not character or not character.PrimaryPart then return nil end local rootPart = character.PrimaryPart local origin = rootPart.Position -- Try up to 10 times to find a valid spot so we don't teleport into a wall for i = 1, 10 do -- 1. Pick a random angle (0 to 360 degrees) local angle = math.rad(math.random(0, 360)) -- 2. Pick a random distance between MIN and MAX local distance = math.random(MIN_DISTANCE, MAX_DISTANCE) -- 3. Calculate the offset local offsetX = math.cos(angle) * distance local offsetZ = math.sin(angle) * distance -- 4. Determine where to check for ground -- We start 50 studs UP in the air at the random spot and look down local castOrigin = origin + Vector3.new(offsetX, 50, offsetZ) local castDirection = Vector3.new(0, -200, 0) -- Look down 200 studs -- 5. Set up Raycast parameters (ignore the player character) local rayParams = RaycastParams.new() rayParams.FilterDescendantsInstances = {character} rayParams.FilterType = Enum.RaycastFilterType.Exclude -- 6. Shoot the ray local result = workspace:Raycast(castOrigin, castDirection, rayParams) if result then -- If we hit something (the floor), that's our target return result.Position + Vector3.new(0, 3, 0) -- Add 3 studs height so we don't get stuck in floor end end return nil -- Could not find a safe spot after 10 tries end local function executeTeleport() local character = player.Character if not character then return end local targetPosition = getRandomPosition() if targetPosition then -- Play Sound local sound = Instance.new("Sound") sound.SoundId = SOUND_ID sound.Parent = character.PrimaryPart sound:Play() Debris:AddItem(sound, 3) -- Move Character (Using PivotTo is more reliable than SetPrimaryPartCFrame) character:PivotTo(CFrame.new(targetPosition)) else print("Could not find a valid spot to teleport.") -- Optional: Reset the button color to indicate failure, or refund the cooldown end end button.MouseButton1Click:Connect(function() if isTeleporting then return end local character = player.Character local humanoid = character and character:FindFirstChild("Humanoid") if not humanoid or humanoid.Health <= 0 then return end isTeleporting = true lastHealth = humanoid.Health button.ImageColor3 = Color3.fromRGB(255, 100, 100) -- Red tint while charging -- Freeze Player local oldWalkSpeed = humanoid.WalkSpeed local oldJumpPower = humanoid.JumpPower humanoid.WalkSpeed = 0 humanoid.JumpPower = 0 local startTime = tick() local connection connection = RunService.Heartbeat:Connect(function() -- 1. Check if died or character missing if not character or not humanoid or humanoid.Health <= 0 then connection:Disconnect() isTeleporting = false return end -- 2. Check for Damage (Decline teleport) if humanoid.Health < lastHealth then connection:Disconnect() isTeleporting = false humanoid.WalkSpeed = oldWalkSpeed humanoid.JumpPower = oldJumpPower button.ImageColor3 = Color3.fromRGB(255, 255, 255) print("Teleport Cancelled: Damage Received") return end lastHealth = humanoid.Health -- 3. Check if time passed if tick() - startTime >= TELEPORT_DELAY then connection:Disconnect() executeTeleport() -- Reset player movement humanoid.WalkSpeed = oldWalkSpeed humanoid.JumpPower = oldJumpPower button.ImageColor3 = Color3.fromRGB(255, 255, 255) isTeleporting = false end end) end)