cool portal gun script from rick and morty
Key RequiredUniversal

cool portal gun script from rick and morty

Universal ScriptkillerXkillerX 2.5K views 41.3K executesUpdated Sep 11, 2026
5.0/ 5(1 votes)
10100% Positive
Lua Script•879 lines (32215 chars)
local SCRIPT_URL = "https://gist.githubusercontent.com/supersayingod902-a11y/a14443f587a465e145a71fd4b420ab70/raw" 

local CoreGui = game:GetService("CoreGui")
local Players = game:GetService("Players")
local TeleportService = game:GetService("TeleportService")
local HttpService = game:GetService("HttpService")
local TweenService = game:GetService("TweenService")
local CollectionService = game:GetService("CollectionService")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

local player = Players.LocalPlayer
local queue_on_tp = queue_on_teleport or (syn and syn.queue_on_teleport) or (fluxus and fluxus.queue_on_teleport) or function() end

if getgenv().RickPortalCleanup then
    getgenv().RickPortalCleanup()
end

local PORTAL_ASSET_ID = "90557902399922"
local PORTAL_TEXTURE = "rbxthumb://type=Asset&id=" .. PORTAL_ASSET_ID .. "&w=420&h=420"
local PORTAL_AUDIO_ID = "rbxassetid://756847338" 
local VOICE_AUDIO_ID = "rbxassetid://1701569142" 
local PORTAL_TAG = "RickPortal_C137_" .. player.UserId 

local activePortals = {}
local connections = {}
local voidPlatform = nil

-- Air Walk State & Platform
local airWalkOn = false
local platformY = 0
local platform = Instance.new("Part")
platform.Name = "AirWalkPlatform"
platform.Anchored = true
platform.Size = Vector3.new(6, 1, 6)
platform.Transparency = 1
platform.CanCollide = false
platform.Parent = workspace

local function wipeAllPortals()
    for _, portalPart in ipairs(activePortals) do
        if portalPart and portalPart.Parent then portalPart:Destroy() end
    end
    table.clear(activePortals)
    for _, portalPart in ipairs(CollectionService:GetTagged(PORTAL_TAG)) do
        if portalPart then portalPart:Destroy() end
    end
    if voidPlatform and voidPlatform.Parent then
        voidPlatform:Destroy()
        voidPlatform = nil
    end
end

wipeAllPortals()

if CoreGui:FindFirstChild("RickPortalGUI") then
    CoreGui.RickPortalGUI:Destroy()
end

-- ==========================================
-- JANKY SCI-FI GADGET UI SETUP
-- ==========================================
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "RickPortalGUI"
screenGui.ResetOnSpawn = false
screenGui.Parent = CoreGui

-- 1. Outer Metal Casing (300 x 430)
local mainFrame = Instance.new("Frame")
mainFrame.Size = UDim2.new(0, 300, 0, 430)
mainFrame.Position = UDim2.new(0, -400, 0.35, -215)
mainFrame.BackgroundColor3 = Color3.fromRGB(35, 38, 42)
mainFrame.BorderSizePixel = 0
mainFrame.Active = true
mainFrame.Draggable = true
mainFrame.Parent = screenGui

local uiCorner = Instance.new("UICorner")
uiCorner.CornerRadius = UDim.new(0, 16)
uiCorner.Parent = mainFrame

local casingStroke = Instance.new("UIStroke")
casingStroke.Color = Color3.fromRGB(20, 22, 25)
casingStroke.Thickness = 4
casingStroke.Parent = mainFrame

-- 2. Gadget Screws
local function addScrew(posX, posY)
    local screw = Instance.new("Frame")
    screw.Size = UDim2.new(0, 12, 0, 12)
    screw.Position = UDim2.new(posX.Scale, posX.Offset, posY.Scale, posY.Offset)
    screw.BackgroundColor3 = Color3.fromRGB(90, 95, 100)
    screw.Parent = mainFrame
    local sCorner = Instance.new("UICorner")
    sCorner.CornerRadius = UDim.new(1, 0)
    sCorner.Parent = screw
    local slot = Instance.new("Frame")
    slot.Size = UDim2.new(0, 8, 0, 2)
    slot.Position = UDim2.new(0.5, -4, 0.5, -1)
    slot.BackgroundColor3 = Color3.fromRGB(20, 20, 20)
    slot.BorderSizePixel = 0
    slot.Rotation = math.random(0, 180)
    slot.Parent = screw
end
addScrew(UDim.new(0, 6), UDim.new(0, 6))
addScrew(UDim.new(1, -18), UDim.new(0, 6))
addScrew(UDim.new(0, 6), UDim.new(1, -18))
addScrew(UDim.new(1, -18), UDim.new(1, -18))

-- 3. Inner Glowing Screen
local innerScreen = Instance.new("Frame")
innerScreen.Size = UDim2.new(1, -30, 1, -30)
innerScreen.Position = UDim2.new(0, 15, 0, 15)
innerScreen.BackgroundColor3 = Color3.fromRGB(12, 18, 14)
innerScreen.ClipsDescendants = false 
innerScreen.Parent = mainFrame

local innerCorner = Instance.new("UICorner")
innerCorner.CornerRadius = UDim.new(0, 10)
innerCorner.Parent = innerScreen

local innerStroke = Instance.new("UIStroke")
innerStroke.Color = Color3.fromRGB(40, 220, 90)
innerStroke.Thickness = 3
innerStroke.Parent = mainFrame 

-- 4. Layered Sagging Hanging Cables with ZIndex Support
local function createSaggingCable(startX, startY, endX, endY, sagDepth, wireColor, customZIndex)
    local z = customZIndex or 6
    local segments = 10
    for i = 0, segments - 1 do
        local t1 = i / segments
        local t2 = (i + 1) / segments
        
        local function getPoint(t)
            local x = startX + (endX - startX) * t
            local y = startY + (endY - startY) * t + sagDepth * (4 * t * (1 - t))
            return x, y
        end
        
        local x1, y1 = getPoint(t1)
        local x2, y2 = getPoint(t2)
        
        local dx = x2 - x1
        local dy = y2 - y1
        local dist = math.sqrt(dx*dx + dy*dy)
        local angle = math.deg(math.atan2(dy, dx))
        
        local seg = Instance.new("Frame")
        seg.Size = UDim2.new(0, dist + 1, 0, 4)
        seg.Position = UDim2.new(0, x1, 0, y1)
        seg.Rotation = angle
        seg.BackgroundColor3 = wireColor
        seg.BorderSizePixel = 0
        seg.ZIndex = z
        seg.Parent = mainFrame
        
        local stroke = Instance.new("UIStroke")
        stroke.Color = Color3.fromRGB(15, 15, 15)
        stroke.Thickness = 1
        stroke.Parent = seg
        
        if i == math.floor(segments / 2) then
            local spark = Instance.new("Frame")
            spark.Size = UDim2.new(0, 7, 0, 7)
            spark.Position = UDim2.new(0.5, -3, 0.5, -3)
            spark.BackgroundColor3 = Color3.fromRGB(255, 140, 0)
            spark.BorderSizePixel = 0
            spark.ZIndex = z + 2
            spark.Parent = seg
            local sc = Instance.new("UICorner")
            sc.CornerRadius = UDim.new(1, 0)
            sc.Parent = spark
            
            task.spawn(function()
                while spark and spark.Parent do
                    spark.Visible = math.random() > 0.3
                    spark.BackgroundColor3 = math.random() > 0.5 and Color3.fromRGB(255, 100, 0) or Color3.fromRGB(255, 220, 50)
                    task.wait(math.random(10, 25) / 100)
                end
            end)
        end
    end
    
    local function addTerminal(px, py)
        local term = Instance.new("Frame")
        term.Size = UDim2.new(0, 6, 0, 8)
        term.Position = UDim2.new(0, px - 3, 0, py - 4)
        term.BackgroundColor3 = Color3.fromRGB(20, 20, 20)
        term.BorderSizePixel = 1
        term.BorderColor3 = Color3.fromRGB(60, 60, 60)
        term.ZIndex = z + 1
        term.Parent = mainFrame
        local tc = Instance.new("UICorner")
        tc.CornerRadius = UDim.new(0, 2)
        tc.Parent = term
    end
    addTerminal(startX, startY)
    addTerminal(endX, endY)
end

createSaggingCable(12, 0, 210, 8, 30, Color3.fromRGB(20, 20, 20), 4)       
createSaggingCable(45, 0, 185, 16, 18, Color3.fromRGB(140, 35, 35), 5)     
createSaggingCable(30, 0, 150, 15, 22, Color3.fromRGB(220, 45, 45), 6)     

createSaggingCable(0, 140, 15, 220, 18, Color3.fromRGB(40, 120, 240), 6)   
createSaggingCable(285, 260, 300, 340, 20, Color3.fromRGB(240, 190, 20), 6) 

task.spawn(function()
    while innerScreen and innerScreen.Parent do
        task.wait(math.random(3, 8))
        innerStroke.Color = Color3.fromRGB(255, 255, 200)
        task.wait(0.05)
        innerStroke.Color = Color3.fromRGB(40, 220, 90)
        task.wait(0.1)
        innerStroke.Color = Color3.fromRGB(255, 140, 0) 
        task.wait(0.05)
        innerStroke.Color = Color3.fromRGB(40, 220, 90)
    end
end)

local slideInTween = TweenService:Create(
    mainFrame, 
    TweenInfo.new(1.2, Enum.EasingStyle.Sine, Enum.EasingDirection.Out), 
    {Position = UDim2.new(0, 20, 0.35, -215)}
)
slideInTween:Play()

local title = Instance.new("TextLabel")
title.Size, title.Position = UDim2.new(1, 0, 0, 32), UDim2.new(0, 0, 0, 10)
title.BackgroundTransparency, title.Text = 1, "⚡ C-137 PORTAL GUN ⚡"
title.TextColor3, title.Font, title.TextSize = Color3.fromRGB(50, 255, 100), Enum.Font.GothamBlack, 15
title.Parent = innerScreen

local quoteLabel = Instance.new("TextLabel")
quoteLabel.Size, quoteLabel.Position = UDim2.new(0.9, 0, 0, 30), UDim2.new(0.05, 0, 0, 38)
quoteLabel.BackgroundTransparency, quoteLabel.Text = 1, "\"Wubba Lubba Dub Dub!\""
quoteLabel.TextColor3, quoteLabel.Font, quoteLabel.TextSize = Color3.fromRGB(170, 255, 180), Enum.Font.SourceSansItalic, 12
quoteLabel.TextWrapped = true
quoteLabel.Parent = innerScreen

local rickQuotes = {
    "\"Wubba Lubba Dub Dub!\"",
    "\"I turned myself into a script, Morty! I'm Script Rick!\"",
    "\"Nobody exists on purpose. Nobody belongs anywhere. Everybody's gonna watch TV.\"",
    "\"To live is to risk it all, otherwise you're just an inert chunk of randomly assembled molecules.\"",
    "\"AIDS! Just kidding. But seriously, grab the portal gun, Morty.\"",
    "\"Listen, Morty, I hate to break it to you, but what people call 'love' is just a chemical reaction.\"",
    "\"Weddings are basically funerals with cake, Morty.\"",
    "\"Existence is pain to a Meeseeks, Jerry, and we will do anything to alleviate that pain!\"",
    "\"Aw, geez, Rick, are we stuck in a Roblox script?\"",
    "\"Science is a lot more art than science, Morty. Lotta people don't get that.\"",
    "\"Boom! Big reveal! I turned us into dimensional travelers! What do you think about that?\""
}

local function setRandomQuote()
    quoteLabel.Text = rickQuotes[math.random(1, #rickQuotes)]
end

local function createButton(text, yPos)
    local btn = Instance.new("TextButton")
    btn.Size = UDim2.new(0.88, 0, 0, 36)
    btn.Position = UDim2.new(0.06, 0, 0, yPos)
    btn.BackgroundColor3 = Color3.fromRGB(20, 35, 25)
    btn.Text = text
    btn.TextColor3 = Color3.fromRGB(180, 255, 190)
    btn.Font = Enum.Font.GothamBold
    btn.TextSize = 12
    btn.Parent = innerScreen

    local corner = Instance.new("UICorner")
    corner.CornerRadius = UDim.new(0, 8)
    corner.Parent = btn

    local btnStroke = Instance.new("UIStroke")
    btnStroke.Color = Color3.fromRGB(40, 160, 70)
    btnStroke.Thickness = 1.5
    btnStroke.Parent = btn

    btn.MouseEnter:Connect(function()
        btn.BackgroundColor3 = Color3.fromRGB(30, 55, 35)
    end)
    btn.MouseLeave:Connect(function()
        if not btn:GetAttribute("ActiveState") then
            btn.BackgroundColor3 = Color3.fromRGB(20, 35, 25)
        end
    end)
    
    return btn
end

local tpPlayerBtn = createButton("Select Player to TP", 80)
local portalGunBtn = createButton("Portal Gun Mode [OFF]", 122)
local airWalkBtn = createButton("Air Walk [OFF]", 164)
local serverHopBtn = createButton("Server Hop (Walk In)", 206)

local closeBtn = createButton("Close Menu", 262)
closeBtn.BackgroundColor3 = Color3.fromRGB(100, 25, 25)
closeBtn.TextColor3 = Color3.fromRGB(255, 200, 200)
local closeStroke = closeBtn:FindFirstChildOfClass("UIStroke")
if closeStroke then closeStroke.Color = Color3.fromRGB(200, 50, 50) end

local footerLabel = Instance.new("TextLabel")
footerLabel.Size = UDim2.new(1, 0, 0, 20)
footerLabel.Position = UDim2.new(0, 0, 1, -22)
footerLabel.BackgroundTransparency = 1
footerLabel.Text = "Dimension C-137 • Interdimensional Cable"
footerLabel.TextColor3 = Color3.fromRGB(60, 120, 70)
footerLabel.Font = Enum.Font.Code
footerLabel.TextSize = 9
footerLabel.Parent = innerScreen

local slidingPanel = Instance.new("Frame")
slidingPanel.Size = UDim2.new(0, 0, 1, 0)
slidingPanel.Position = UDim2.new(1, -10, 0, 0)
slidingPanel.BackgroundColor3 = Color3.fromRGB(35, 38, 42)
slidingPanel.BorderSizePixel = 0
slidingPanel.ClipsDescendants = true
slidingPanel.ZIndex = -1
slidingPanel.Parent = mainFrame

local panelCorner = Instance.new("UICorner")
panelCorner.CornerRadius = UDim.new(0, 12)
panelCorner.Parent = slidingPanel

local panelStroke = Instance.new("UIStroke")
panelStroke.Color = Color3.fromRGB(100, 105, 110)
panelStroke.Thickness = 3
panelStroke.Parent = slidingPanel

local panelInner = Instance.new("Frame")
panelInner.Size = UDim2.new(1, -16, 1, -16)
panelInner.Position = UDim2.new(0, 8, 0, 8)
panelInner.BackgroundColor3 = Color3.fromRGB(12, 18, 14)
panelInner.Parent = slidingPanel
local pInnerCorner = Instance.new("UICorner")
pInnerCorner.CornerRadius = UDim.new(0, 8)
pInnerCorner.Parent = panelInner

local panelTitle = Instance.new("TextLabel")
panelTitle.Size = UDim2.new(1, 0, 0, 32)
panelTitle.BackgroundTransparency = 1
panelTitle.Text = "🌀 DIMENSION TARGETS 🌀"
panelTitle.TextColor3 = Color3.fromRGB(50, 255, 100)
panelTitle.Font = Enum.Font.GothamBold
panelTitle.TextSize = 10
panelTitle.Parent = panelInner

local scrollingList = Instance.new("ScrollingFrame")
scrollingList.Size = UDim2.new(1, -12, 1, -40)
scrollingList.Position = UDim2.new(0, 6, 0, 32)
scrollingList.BackgroundTransparency = 1
scrollingList.BorderSizePixel = 0
scrollingList.CanvasSize = UDim2.new(0, 0, 0, 0)
scrollingList.ScrollBarThickness = 4
scrollingList.Parent = panelInner

local uiListLayout = Instance.new("UIListLayout")
uiListLayout.SortOrder = Enum.SortOrder.LayoutOrder
uiListLayout.Padding = UDim.new(0, 6)
uiListLayout.Parent = scrollingList

local panelOpen = false

-- ==========================================
-- PORTAL & AIR WALK LOGIC
-- ==========================================
RunService.RenderStepped:Connect(function()
    local char = player.Character
    local root = char and char:FindFirstChild("HumanoidRootPart")
    if airWalkOn and root then
        platform.Position = Vector3.new(root.Position.X, platformY, root.Position.Z)
        platform.CanCollide = true
    else
        platform.CanCollide = false
    end
end)

airWalkBtn.MouseButton1Click:Connect(function()
    setRandomQuote()
    local char = player.Character
    local root = char and char:FindFirstChild("HumanoidRootPart")
    if root then
        -- Flush feet offset (-3.4) for equal positioning across all games
        platformY = root.Position.Y - 3.4
    end
    
    airWalkOn = not airWalkOn
    platform.CanCollide = airWalkOn

    if airWalkOn then
        airWalkBtn:SetAttribute("ActiveState", true)
        airWalkBtn.Text = "Air Walk [ON]"
        airWalkBtn.BackgroundColor3 = Color3.fromRGB(40, 140, 50)
    else
        airWalkBtn:SetAttribute("ActiveState", false)
        airWalkBtn.Text = "Air Walk [OFF]"
        airWalkBtn.BackgroundColor3 = Color3.fromRGB(20, 35, 25)
    end
end)

local function playTeleportVoice()
    local char = player.Character
    local root = char and char:FindFirstChild("HumanoidRootPart")
    if root then
        local voiceSfx = Instance.new("Sound")
        voiceSfx.SoundId = VOICE_AUDIO_ID
        voiceSfx.Volume = 3
        voiceSfx.Parent = root
        voiceSfx:Play()
        task.spawn(function()
            voiceSfx.Ended:Wait()
            voiceSfx:Destroy()
        end)
    end
end

local function createPortalInstance(cframe)
    local pos = cframe.Position
    local _, yRot, _ = cframe:ToOrientation()
    local verticalCFrame = CFrame.new(pos) * CFrame.Angles(0, yRot, 0)

    local portalPart = Instance.new("Part")
    portalPart.Size = Vector3.new(0.1, 0.1, 0.1) 
    portalPart.CFrame = verticalCFrame
    portalPart.Anchored = true
    portalPart.CanCollide = false
    portalPart.Transparency = 1
    portalPart.Parent = workspace
    
    CollectionService:AddTag(portalPart, PORTAL_TAG)
    table.insert(activePortals, portalPart)

    local portalSfx = Instance.new("Sound")
    portalSfx.SoundId = PORTAL_AUDIO_ID
    portalSfx.Volume = 3
    portalSfx.RollOffMaxDistance = 150
    portalSfx.Parent = portalPart
    portalSfx:Play()

    local portalLight = Instance.new("PointLight")
    portalLight.Color = Color3.fromRGB(50, 255, 80)
    portalLight.Range = 15
    portalLight.Brightness = 3
    portalLight.Parent = portalPart

    local sparks = Instance.new("ParticleEmitter")
    sparks.Color = ColorSequence.new(Color3.fromRGB(50, 255, 80))
    sparks.Size = NumberSequence.new({NumberSequenceKeypoint.new(0, 0.3), NumberSequenceKeypoint.new(1, 0)})
    sparks.Lifetime = NumberRange.new(0.5, 1.2)
    sparks.Rate = 25
    sparks.Speed = NumberRange.new(3, 7)
    sparks.SpreadAngle = Vector2.new(360, 360)
    sparks.EmissionDirection = Enum.NormalId.Front
    sparks.Parent = portalPart

    local function createSurfaceFace(normalFace)
        local surf = Instance.new("SurfaceGui")
        surf.Face = normalFace
        surf.SizingMode = Enum.SurfaceGuiSizingMode.PixelsPerStud
        surf.PixelsPerStud = 50
        surf.LightInfluence = 0
        surf.Parent = portalPart

        local frontSwirl = Instance.new("ImageLabel")
        frontSwirl.Size = UDim2.new(1, 0, 1, 0)
        frontSwirl.BackgroundTransparency = 1
        frontSwirl.Image = PORTAL_TEXTURE
        frontSwirl.AnchorPoint = Vector2.new(0.5, 0.5)
        frontSwirl.Position = UDim2.new(0.5, 0, 0.5, 0)
        frontSwirl.Parent = surf

        local corner2 = Instance.new("UICorner")
        corner2.CornerRadius = UDim.new(0.5, 0)
        corner2.Parent = frontSwirl

        return frontSwirl
    end

    local fFront = createSurfaceFace(Enum.NormalId.Front)
    local bFront = createSurfaceFace(Enum.NormalId.Back)

    local tweenInfo = TweenInfo.new(0.35, Enum.EasingStyle.Back, Enum.EasingDirection.Out)
    local openTween = TweenService:Create(portalPart, tweenInfo, {Size = Vector3.new(7, 7, 0.1)})
    openTween:Play()

    task.spawn(function()
        while portalPart and portalPart.Parent do
            local fRot = (fFront.Rotation + 8) % 360
            fFront.Rotation = fRot
            bFront.Rotation = fRot
            task.wait(0.03)
        end
    end)

    return portalPart
end

local function refreshPlayerList()
    for _, child in ipairs(scrollingList:GetChildren()) do
        if child:IsA("TextButton") then child:Destroy() end
    end

    local count = 0
    for _, p in ipairs(Players:GetPlayers()) do
        if p ~= player then
            count = count + 1
            local pBtn = Instance.new("TextButton")
            pBtn.Size = UDim2.new(1, 0, 0, 32)
            pBtn.BackgroundColor3 = Color3.fromRGB(22, 38, 25)
            pBtn.TextColor3 = Color3.fromRGB(180, 255, 180)
            pBtn.Text = "👤 " .. p.DisplayName
            pBtn.Font = Enum.Font.Gotham
            pBtn.TextSize = 12
            pBtn.Parent = scrollingList

            local c = Instance.new("UICorner")
            c.CornerRadius = UDim.new(0, 6)
            c.Parent = pBtn

            local bStroke = Instance.new("UIStroke")
            bStroke.Color = Color3.fromRGB(40, 110, 50)
            bStroke.Thickness = 1
            bStroke.Parent = pBtn

            task.spawn(function()
                local isFriend = false
                pcall(function() isFriend = player:IsFriendsWith(p.UserId) end)
                if isFriend then
                    pBtn.BackgroundColor3 = Color3.fromRGB(45, 20, 20)
                    pBtn.TextColor3 = Color3.fromRGB(255, 120, 120)
                    bStroke.Color = Color3.fromRGB(150, 40, 40)
                    pBtn.Text = "❤️ " .. p.DisplayName
                end
            end)

            pBtn.MouseButton1Click:Connect(function()
                setRandomQuote()
                wipeAllPortals()
                panelOpen = false
                tpPlayerBtn:SetAttribute("ActiveState", false)
                TweenService:Create(slidingPanel, TweenInfo.new(0.3, Enum.EasingStyle.Quad, Enum.EasingDirection.In), {Size = UDim2.new(0, 0, 1, 0)}):Play()
                tpPlayerBtn.BackgroundColor3 = Color3.fromRGB(20, 35, 25)

                local char = player.Character
                local root = char and char:FindFirstChild("HumanoidRootPart")
                if not root then return end

                local tpPortal = createPortalInstance(root.CFrame * CFrame.new(0, 0, -5))
                tpPlayerBtn.Text = "Walk in Portal to TP!"

                local touched = false
                local touchConn
                touchConn = tpPortal.Touched:Connect(function(hit)
                    if touched or hit.Parent ~= char then return end
                    touched = true
                    tpPlayerBtn.Text = "Jumping Dimensions..."
                    playTeleportVoice()

                    task.spawn(function()
                        local targetPlayer = p
                        local targetChar = targetPlayer.Character
                        
                        if not targetChar then
                            tpPlayerBtn.Text = "Target Doesn't Exist!"
                            task.wait(1.5)
                            tpPlayerBtn.Text = "Select Player to TP"
                            return
                        end

                        local targetPivot = targetChar:GetPivot()
                        local actualRoot = targetChar:FindFirstChild("HumanoidRootPart") or targetChar.PrimaryPart
                        
                        if actualRoot then
                            root.CFrame = actualRoot.CFrame * CFrame.new(0, 0, -4)
                            tpPlayerBtn.Text = "Select Player to TP"
                        else
                            root.CFrame = targetPivot * CFrame.new(0, 5, 0)
                            root.Anchored = true
                            pcall(function() player:RequestStreamAroundAsync(targetPivot.Position) end)
                            local timeout = tick() + 5
                            while tick() < timeout do
                                actualRoot = targetChar:FindFirstChild("HumanoidRootPart") or targetChar.PrimaryPart
                                if actualRoot then break end
                                task.wait(0.05) 
                            end

                            if actualRoot then
                                root.CFrame = actualRoot.CFrame * CFrame.new(0, 0, -4)
                            else
                                tpPlayerBtn.Text = "Target Ghosted!"
                                task.wait(1.5)
                            end
                            root.Anchored = false
                            tpPlayerBtn.Text = "Select Player to TP"
                        end
                    end)

                    task.wait(1)
                    wipeAllPortals()
                    if touchConn then touchConn:Disconnect() end
                end)
            end)
        end
    end
    scrollingList.CanvasSize = UDim2.new(0, 0, 0, count * 38)
    return count
end

tpPlayerBtn.MouseButton1Click:Connect(function()
    setRandomQuote()
    local otherCount = refreshPlayerList()

    if otherCount == 0 then
        tpPlayerBtn.Text = "No Other Players!"
        task.wait(1.5)
        tpPlayerBtn.Text = "Select Player to TP"
        if panelOpen then
            panelOpen = false
            tpPlayerBtn:SetAttribute("ActiveState", false)
            TweenService:Create(slidingPanel, TweenInfo.new(0.3, Enum.EasingStyle.Quad, Enum.EasingDirection.In), {Size = UDim2.new(0, 0, 1, 0)}):Play()
            tpPlayerBtn.BackgroundColor3 = Color3.fromRGB(20, 35, 25)
        end
        return
    end

    panelOpen = not panelOpen
    local tweenInfo = TweenInfo.new(0.3, Enum.EasingStyle.Back, Enum.EasingDirection.Out)
    
    if panelOpen then
        tpPlayerBtn:SetAttribute("ActiveState", true)
        TweenService:Create(slidingPanel, tweenInfo, {Size = UDim2.new(0, 180, 1, 0)}):Play()
        tpPlayerBtn.BackgroundColor3 = Color3.fromRGB(40, 140, 50)
    else
        tpPlayerBtn:SetAttribute("ActiveState", false)
        TweenService:Create(slidingPanel, tweenInfo, {Size = UDim2.new(0, 0, 1, 0)}):Play()
        tpPlayerBtn.BackgroundColor3 = Color3.fromRGB(20, 35, 25)
    end
end)

Players.PlayerAdded:Connect(function()
    if panelOpen then refreshPlayerList() end
end)

Players.PlayerRemoving:Connect(function()
    if panelOpen then 
        local remaining = refreshPlayerList()
        if remaining == 0 then
            panelOpen = false
            tpPlayerBtn:SetAttribute("ActiveState", false)
            TweenService:Create(slidingPanel, TweenInfo.new(0.3, Enum.EasingStyle.Quad, Enum.EasingDirection.In), {Size = UDim2.new(0, 0, 1, 0)}):Play()
            tpPlayerBtn.BackgroundColor3 = Color3.fromRGB(20, 35, 25)
        end
    end
end)

local portalGunActive = false
local isTeleporting = false
local isSpawning = false 
local TELEPORT_COOLDOWN = 1.5

local function smartJumpToCFrame(root, targetCFrame)
    local targetPos = targetCFrame.Position
    local rayParams = RaycastParams.new()
    rayParams.FilterDescendantsInstances = {player.Character, unpack(activePortals)}
    rayParams.FilterType = Enum.RaycastFilterType.Exclude
    
    -- If Air Walk is ON and we have a void platform, snap the air walk Y to it
    if airWalkOn then
        root.CFrame = targetCFrame
        if voidPlatform then
            platformY = voidPlatform.Position.Y
        else
            platformY = targetPos.Y - 3.4
        end
        return
    end

    local initialCheck = workspace:Raycast(targetPos + Vector3.new(0, 5, 0), Vector3.new(0, -1000, 0), rayParams)
    
    if initialCheck and initialCheck.Instance then
        root.CFrame = targetCFrame
        return
    end

    root.CFrame = targetCFrame * CFrame.new(0, 4, 0) 
    root.Anchored = true
    pcall(function() player:RequestStreamAroundAsync(targetPos) end)
    
    local timeout = tick() + 2.5
    while tick() < timeout do
        local rayResult = workspace:Raycast(root.Position, Vector3.new(0, -1000, 0), rayParams)
        if rayResult and rayResult.Instance then break end
        task.wait(0.05)
    end
    
    if root and root.Parent then root.Anchored = false end
end

local mouseInputConn = UserInputService.InputBegan:Connect(function(input, gameProcessed)
    if gameProcessed then return end
    if not portalGunActive then return end
    if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
    if isSpawning then return end
    
    local mouse = player:GetMouse()
    local hitPart = mouse.Target
    local hitPos = mouse.Hit
    local char = player.Character
    local root = char and char:FindFirstChild("HumanoidRootPart")

    if hitPos and root then
        if not hitPart and not airWalkOn then
            return
        end

        isSpawning = true 
        wipeAllPortals()

        local exitPortal = createPortalInstance(CFrame.lookAt(hitPos.Position + Vector3.new(0, 3.5, 0), root.Position))

        -- If placed in the air (void) with Air Walk ON, spawn an invisible solid baseplate underneath!
        if not hitPart and airWalkOn then
            voidPlatform = Instance.new("Part")
            voidPlatform.Name = "VoidBaseplate"
            voidPlatform.Size = Vector3.new(60, 1, 60)
            voidPlatform.Position = Vector3.new(hitPos.Position.X, hitPos.Position.Y, hitPos.Position.Z)
            voidPlatform.Anchored = true
            voidPlatform.Transparency = 1
            voidPlatform.CanCollide = true
            voidPlatform.Parent = workspace
            platformY = hitPos.Position.Y
        end

        local entrancePortal = createPortalInstance(root.CFrame * CFrame.new(0, 0, -5))

        entrancePortal.Touched:Connect(function(hit)
            if isTeleporting or hit.Parent ~= char then return end
            isTeleporting = true
            task.spawn(function()
                smartJumpToCFrame(root, exitPortal.CFrame * CFrame.new(0, 0, -6))
                task.wait(TELEPORT_COOLDOWN)
                isTeleporting = false
            end)
        end)

        exitPortal.Touched:Connect(function(hit)
            if isTeleporting or hit.Parent ~= char then return end
            isTeleporting = true
            task.spawn(function()
                smartJumpToCFrame(root, entrancePortal.CFrame * CFrame.new(0, 0, -6))
                task.wait(TELEPORT_COOLDOWN)
                isTeleporting = false
            end)
        end)
        
        task.wait(0.35)
        isSpawning = false 
    end
end)
table.insert(connections, mouseInputConn)

portalGunBtn.MouseButton1Click:Connect(function()
    portalGunActive = not portalGunActive
    setRandomQuote()

    if portalGunActive then
        portalGunBtn:SetAttribute("ActiveState", true)
        portalGunBtn.Text = "Portal Gun Mode [ON]"
        portalGunBtn.BackgroundColor3 = Color3.fromRGB(40, 140, 50)
    else
        portalGunBtn:SetAttribute("ActiveState", false)
        portalGunBtn.Text = "Portal Gun Mode [OFF]"
        portalGunBtn.BackgroundColor3 = Color3.fromRGB(20, 35, 25)
        wipeAllPortals()
    end
end)

local isHopping = false
serverHopBtn.MouseButton1Click:Connect(function()
    setRandomQuote()

    if isHopping then
        isHopping = false
        serverHopBtn.Text = "Server Hop (Walk In)"
        serverHopBtn.BackgroundColor3 = Color3.fromRGB(20, 35, 25)
        wipeAllPortals() 
        return
    end

    isHopping = true
    serverHopBtn.Text = "Cancel Portal..."
    serverHopBtn.BackgroundColor3 = Color3.fromRGB(180, 80, 30)

    task.spawn(function()
        local url = "https://games.roblox.com/v1/games/" .. game.PlaceId .. "/servers/Public?sortOrder=Desc&excludeFullGames=true&limit=100"
        local req = (request or http_request or syn and syn.request)
        
        if not req then
            serverHopBtn.Text = "HTTP Blocked!"
            task.wait(1.5)
            isHopping = false
            serverHopBtn.Text = "Server Hop (Walk In)"
            serverHopBtn.BackgroundColor3 = Color3.fromRGB(20, 35, 25)
            return
        end

        local response = req({Url = url, Method = "GET"})
        local targetServerId = nil

        if response and response.Body then
            local data = HttpService:JSONDecode(response.Body)
            if data and data.data then
                for _, server in ipairs(data.data) do
                    if server.playing < server.maxPlayers and server.id ~= game.JobId then
                        targetServerId = server.id
                        break
                    end
                end
            end
        end

        if not targetServerId then
            serverHopBtn.Text = "No Server Found!"
            task.wait(1.5)
            isHopping = false
            serverHopBtn.Text = "Server Hop (Walk In)"
            serverHopBtn.BackgroundColor3 = Color3.fromRGB(20, 35, 25)
            return
        end

        local root = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
        if not root then return end

        wipeAllPortals() 
        local hopPortal = createPortalInstance(root.CFrame * CFrame.new(0, 0, -5))
        serverHopBtn.Text = "Walk in Portal!"

        local touched = false
        hopPortal.Touched:Connect(function(hit)
            if touched or not isHopping then return end
            if hit.Parent == player.Character then
                touched = true
                serverHopBtn.Text = "Hopping Server..."
                playTeleportVoice()

                if SCRIPT_URL ~= "" then
                    pcall(function()
                        queue_on_tp('loadstring(game:HttpGet("' .. SCRIPT_URL .. '"))()')
                    end)
                end
                TeleportService:TeleportToPlaceInstance(game.PlaceId, targetServerId, player)
            end
        end)
    end)
end)

local function fullCleanup()
    wipeAllPortals()
    if platform then platform:Destroy() end
    for _, conn in ipairs(connections) do
        conn:Disconnect()
    end
    table.clear(connections)
    if screenGui then screenGui:Destroy() end
end

getgenv().RickPortalCleanup = fullCleanup

closeBtn.MouseButton1Click:Connect(function()
    local slideOutTween = TweenService:Create(
        mainFrame, 
        TweenInfo.new(0.8, Enum.EasingStyle.Sine, Enum.EasingDirection.In), 
        {Position = UDim2.new(0, -400, 0.35, -215)}
    )
    slideOutTween:Play()
    slideOutTween.Completed:Wait()
    fullCleanup()
end)

Features & Information

it includes teleport to player AND if your friends are in game it changes the color of the username to see who's who easier server hop portal air walk and portal gun mode (which is just click to tp basically)

Community Comments (3)

iluvaotiluvaotSep 11, 2026

good idea id be down to help on feature patchez and updates

purpul_g0ypurpul_g0ySep 19, 2026

@iluvaot scriptblox cut the text because its too long, post it on a github gist and send the loadstring of it

Replying to @purpul_g0y
iluvaotiluvaotSep 21, 2026

@purpul_g0y ill juzt make it a script

More Scripts for Universal Scripts