
KeylessUniversal

--[[
Reincarnation Teleportation
made by Vighnesh
place waypoints anywhere, see em from far away with a beam,
teleport back to em whenever. rename/delete if you mess up.
v1 - basic waypoints + teleport
v1.1 - fade transition + safe landing raycast (no more falling thru map)
v1.2 - beam textures/colors, settings tab, reset button
v1.3 - per-waypoint colors + off screen compass arrow + sorted dropdown
drop this in StarterPlayerScripts (or wherever u load scripts from)
heads up: rayfield changes their api sometimes, if Dropdown/Slider stuff
breaks check https://github.com/SiriusSoftwareLtd/Rayfield
]]
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local LocalPlayer = Players.LocalPlayer
local Rayfield = loadstring(game:HttpGet('https://sirius.menu/rayfield'))()
-- config, tweak these if u want
local CONFIG = {
TeleportFadeTime = 0.5,
SafeLandingOffset = 3,
BeamHeight = 2000,
ShowBeams = true,
BeamTextureId = "", -- stick your own asset id here if u want a scrolling texture, leave blank otherwise
}
local Waypoints = {}
local SelectedWaypoint = nil
local WaypointCounter = 0
local IsTeleporting = false
-- colors cycle through this so waypoints don't all look the same
local BEAM_PALETTE = {
Color3.fromRGB(60, 200, 255), -- cyan
Color3.fromRGB(255, 130, 80), -- orange
Color3.fromRGB(140, 255, 120), -- green
Color3.fromRGB(255, 220, 80), -- yellow
Color3.fromRGB(200, 120, 255), -- purple
Color3.fromRGB(255, 110, 190), -- pink
}
-- fade to black overlay, reused every teleport so we're not making a new gui each time
local FadeGui = Instance.new("ScreenGui")
FadeGui.Name = "RT_FadeGui"
FadeGui.IgnoreGuiInset = true
FadeGui.DisplayOrder = 999
FadeGui.ResetOnSpawn = false
FadeGui.Parent = LocalPlayer:WaitForChild("PlayerGui")
local FadeFrame = Instance.new("Frame")
FadeFrame.Name = "Fade"
FadeFrame.Size = UDim2.new(1, 0, 1, 0)
FadeFrame.BackgroundColor3 = Color3.new(0, 0, 0)
FadeFrame.BackgroundTransparency = 1
FadeFrame.BorderSizePixel = 0
FadeFrame.ZIndex = 999
FadeFrame.Parent = FadeGui
-- compass arrow, points at selected waypoint when it's off screen
local CompassGui = Instance.new("ScreenGui")
CompassGui.Name = "RT_CompassGui"
CompassGui.IgnoreGuiInset = true
CompassGui.ResetOnSpawn = false
CompassGui.DisplayOrder = 998
CompassGui.Parent = LocalPlayer:WaitForChild("PlayerGui")
local CompassArrow = Instance.new("TextLabel")
CompassArrow.Name = "CompassArrow"
CompassArrow.AnchorPoint = Vector2.new(0.5, 0.5)
CompassArrow.Size = UDim2.fromOffset(36, 36)
CompassArrow.BackgroundTransparency = 1
CompassArrow.Text = "▲"
CompassArrow.TextColor3 = Color3.fromRGB(60, 200, 255)
CompassArrow.TextStrokeTransparency = 0
CompassArrow.TextStrokeColor3 = Color3.new(0, 0, 0)
CompassArrow.Font = Enum.Font.GothamBold
CompassArrow.TextScaled = true
CompassArrow.Visible = false
CompassArrow.ZIndex = 998
CompassArrow.Parent = CompassGui
local function updateCompass()
local hrp = LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("HumanoidRootPart")
if not SelectedWaypoint or not hrp then
CompassArrow.Visible = false
return
end
local camera = workspace.CurrentCamera
if not camera then
CompassArrow.Visible = false
return
end
local viewportPoint, onScreen = camera:WorldToViewportPoint(SelectedWaypoint.Position)
if onScreen and viewportPoint.Z > 0 then
-- already on screen, don't need the arrow
CompassArrow.Visible = false
return
end
local viewportSize = camera.ViewportSize
local center = Vector2.new(viewportSize.X / 2, viewportSize.Y / 2)
local delta = Vector2.new(viewportPoint.X, viewportPoint.Y) - center
if viewportPoint.Z < 0 then
delta = -delta -- flip when point is behind camera, roblox does this weird thing
end
if delta.Magnitude < 1 then
delta = Vector2.new(0, -1)
end
local angle = math.atan2(delta.Y, delta.X)
local radius = math.min(center.X, center.Y) - 60
CompassArrow.Position = UDim2.new(0.5, math.cos(angle) * radius, 0.5, math.sin(angle) * radius)
CompassArrow.Rotation = math.deg(angle) + 90
CompassArrow.TextColor3 = SelectedWaypoint.Color or Color3.fromRGB(60, 200, 255)
CompassArrow.Visible = true
end
-- makes the beam + marker + label for a waypoint
local function createWaypointVisual(position, color)
color = color or BEAM_PALETTE[1]
local lightColor = color:Lerp(Color3.new(1, 1, 1), 0.5)
local anchor = Instance.new("Part")
anchor.Name = "RT_WaypointAnchor"
anchor.Anchored = true
anchor.CanCollide = false
anchor.CanQuery = false
anchor.CanTouch = false
anchor.Transparency = 1
anchor.Size = Vector3.new(1, 1, 1)
anchor.Position = position
anchor.Parent = workspace
local topPart = Instance.new("Part")
topPart.Name = "RT_WaypointTop"
topPart.Anchored = true
topPart.CanCollide = false
topPart.CanQuery = false
topPart.CanTouch = false
topPart.Transparency = 1
topPart.Size = Vector3.new(1, 1, 1)
topPart.Position = position + Vector3.new(0, CONFIG.BeamHeight, 0)
topPart.Parent = anchor
local att0 = Instance.new("Attachment", anchor)
local att1 = Instance.new("Attachment", topPart)
local beam = Instance.new("Beam")
beam.Name = "RT_Beam"
beam.Attachment0 = att0
beam.Attachment1 = att1
beam.Width0 = 2
beam.Width1 = 0.15
beam.FaceCamera = true
beam.LightEmission = 1
beam.LightInfluence = 0
beam.Segments = 25
beam.Color = ColorSequence.new({
ColorSequenceKeypoint.new(0, color),
ColorSequenceKeypoint.new(0.5, lightColor),
ColorSequenceKeypoint.new(1, Color3.fromRGB(255, 255, 255)),
})
beam.Transparency = NumberSequence.new({
NumberSequenceKeypoint.new(0, 0.05),
NumberSequenceKeypoint.new(0.85, 0.35),
NumberSequenceKeypoint.new(1, 1),
})
if CONFIG.BeamTextureId ~= "" then
beam.Texture = CONFIG.BeamTextureId
beam.TextureMode = Enum.TextureMode.Wrap
beam.TextureLength = 4
beam.TextureSpeed = 1.2
end
beam.Enabled = CONFIG.ShowBeams
beam.Parent = anchor
local marker = Instance.new("Part")
marker.Name = "RT_WaypointMarker"
marker.Shape = Enum.PartType.Ball
marker.Anchored = true
marker.CanCollide = false
marker.CanQuery = false
marker.CanTouch = false
marker.Material = Enum.Material.Neon
marker.Color = color
marker.Size = Vector3.new(1.6, 1.6, 1.6)
marker.Position = position
marker.Transparency = CONFIG.ShowBeams and 0 or 1
marker.Parent = anchor
local markerLight = Instance.new("PointLight")
markerLight.Color = lightColor
markerLight.Range = 16
markerLight.Brightness = 2
markerLight.Parent = marker
local sparkles = Instance.new("ParticleEmitter")
sparkles.Color = ColorSequence.new(lightColor)
sparkles.Size = NumberSequence.new({
NumberSequenceKeypoint.new(0, 0.4),
NumberSequenceKeypoint.new(1, 0),
})
sparkles.Transparency = NumberSequence.new({
NumberSequenceKeypoint.new(0, 0.2),
NumberSequenceKeypoint.new(1, 1),
})
sparkles.Lifetime = NumberRange.new(1.5, 2.5)
sparkles.Rate = 12
sparkles.Speed = NumberRange.new(3, 5)
sparkles.SpreadAngle = Vector2.new(15, 15)
sparkles.Acceleration = Vector3.new(0, 4, 0)
sparkles.Enabled = CONFIG.ShowBeams
sparkles.Parent = marker
local billboard = Instance.new("BillboardGui")
billboard.Name = "RT_Billboard"
billboard.Adornee = anchor
billboard.AlwaysOnTop = true
billboard.Size = UDim2.new(0, 220, 0, 56)
billboard.StudsOffset = Vector3.new(0, 4, 0)
billboard.MaxDistance = 100000
billboard.Enabled = CONFIG.ShowBeams
billboard.Parent = anchor
local nameLabel = Instance.new("TextLabel")
nameLabel.Name = "NameLabel"
nameLabel.Size = UDim2.new(1, 0, 0.55, 0)
nameLabel.BackgroundTransparency = 1
nameLabel.TextColor3 = Color3.new(1, 1, 1)
nameLabel.TextStrokeTransparency = 0
nameLabel.Font = Enum.Font.GothamBold
nameLabel.TextScaled = true
nameLabel.Parent = billboard
local distLabel = Instance.new("TextLabel")
distLabel.Name = "DistanceLabel"
distLabel.Size = UDim2.new(1, 0, 0.45, 0)
distLabel.Position = UDim2.new(0, 0, 0.55, 0)
distLabel.BackgroundTransparency = 1
distLabel.TextColor3 = Color3.fromRGB(180, 220, 255)
distLabel.TextStrokeTransparency = 0
distLabel.Font = Enum.Font.Gotham
distLabel.TextScaled = true
distLabel.Parent = billboard
return anchor, beam, marker, sparkles, billboard, nameLabel, distLabel
end
local function getHRP()
local char = LocalPlayer.Character
return char and char:FindFirstChild("HumanoidRootPart")
end
local RefreshDropdown -- gets set once we build the ui further down
local function findWaypointByName(name)
for _, wp in ipairs(Waypoints) do
if wp.Name == name then
return wp
end
end
return nil
end
local function placeWaypoint()
local hrp = getHRP()
if not hrp then
Rayfield:Notify({ Title = "Reincarnation Teleportation", Content = "cant find your character yet, try again in a sec", Duration = 4 })
return
end
local position = hrp.Position
WaypointCounter += 1
local defaultName = "Waypoint " .. WaypointCounter
local color = BEAM_PALETTE[((WaypointCounter - 1) % #BEAM_PALETTE) + 1]
local anchor, beam, marker, sparkles, billboard, nameLabel, distLabel = createWaypointVisual(position, color)
nameLabel.Text = defaultName
local data = {
Name = defaultName,
Position = position,
Color = color,
Anchor = anchor,
Beam = beam,
Marker = marker,
Sparkles = sparkles,
Billboard = billboard,
NameLabel = nameLabel,
DistanceLabel = distLabel,
}
table.insert(Waypoints, data)
SelectedWaypoint = data
if RefreshDropdown then RefreshDropdown(defaultName) end
Rayfield:Notify({ Title = "Waypoint Placed", Content = defaultName .. " placed", Duration = 3 })
end
local function removeWaypoint(data)
if not data then return end
if data.Anchor then data.Anchor:Destroy() end
for i, wp in ipairs(Waypoints) do
if wp == data then
table.remove(Waypoints, i)
break
end
end
if SelectedWaypoint == data then
SelectedWaypoint = Waypoints[1]
end
if RefreshDropdown then
RefreshDropdown(SelectedWaypoint and SelectedWaypoint.Name or nil)
end
end
local function renameWaypoint(data, newName)
if not data or not newName or newName == "" then return end
if findWaypointByName(newName) then
Rayfield:Notify({ Title = "Reincarnation Teleportation", Content = "already got a waypoint with that name", Duration = 3 })
return
end
data.Name = newName
data.NameLabel.Text = newName
if RefreshDropdown then RefreshDropdown(newName) end
end
-- builds a filter list of every player's character so raycasts/overlap
-- checks don't land you on top of someone standing near the waypoint
local function getCharacterFilterList()
local list = {}
for _, player in ipairs(Players:GetPlayers()) do
if player.Character then
table.insert(list, player.Character)
end
end
return list
end
-- checks if a spot has solid stuff overlapping it (used so we never drop ppl INTO geometry)
local function isPositionStuck(position)
local overlapParams = OverlapParams.new()
overlapParams.FilterType = Enum.RaycastFilterType.Exclude
overlapParams.FilterDescendantsInstances = getCharacterFilterList()
-- roughly the size of a standing character's lower half
local checkSize = Vector3.new(2.5, 5, 2.5)
local checkCFrame = CFrame.new(position + Vector3.new(0, 2.5, 0))
local parts = workspace:GetPartBoundsInBox(checkCFrame, checkSize, overlapParams)
for _, part in ipairs(parts) do
if part.CanCollide then
return true
end
end
return false
end
-- nudges a position straight up until it's not overlapping anything solid, capped
-- so it can't run away and fling the player into the sky
local function unstickPosition(position)
local attempts = 0
local nudged = position
while isPositionStuck(nudged) and attempts < 15 do
nudged += Vector3.new(0, 1, 0)
attempts += 1
end
return nudged
end
-- raycast down to find real ground so we don't teleport ppl into a wall/void.
-- this used to sometimes land people way too high (hit a leaf/railing/other
-- non-collidable clutter instead of the actual floor) or straight into the
-- ground (raycast missed entirely and fell back to the raw stored position).
-- fixed by: ignoring non-collidable junk, skipping past walls/ceilings to find
-- an actual floor-like surface, sanity-checking the result, and unsticking
-- the final spot if it still ends up overlapping something solid.
local function findSafeLandingPosition(position)
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = getCharacterFilterList()
params.RespectCanCollide = true -- skip decorative/non-collide junk entirely
params.IgnoreWater = true -- land on the real ground under water, not the surface
local rayOrigin = position + Vector3.new(0, 300, 0)
local landingPoint = nil
-- step down through the world up to a few times: if we hit something
-- that isn't floor-like (a wall, a ceiling, a steep roof) keep casting
-- from just below that hit until we land on an actual floor or give up
for attempt = 1, 4 do
local result = workspace:Raycast(rayOrigin, Vector3.new(0, -5000, 0), params)
if not result then
break
end
if result.Normal.Y > 0.5 then
-- normal points mostly upward, this is a floor, good to go
landingPoint = result.Position
break
end
-- not floor-like, dip below it and keep looking
rayOrigin = result.Position - Vector3.new(0, 1, 0)
end
local candidate
if landingPoint then
-- sanity check: if the floor we found is wildly far from where the
-- waypoint was originally placed, something's off (e.g. we skipped
-- through into a basement) — don't trust it, use the stored spot instead
if math.abs(landingPoint.Y - position.Y) > 300 then
candidate = position + Vector3.new(0, CONFIG.SafeLandingOffset, 0)
else
candidate = landingPoint + Vector3.new(0, CONFIG.SafeLandingOffset, 0)
end
else
-- raycast found nothing at all (void / unloaded terrain), fall back
-- to the stored position
candidate = position + Vector3.new(0, CONFIG.SafeLandingOffset, 0)
end
-- last line of defense: whatever we ended up with, make sure it's not
-- actually overlapping solid geometry before we send the player there
return unstickPosition(candidate)
end
local function teleportTo(data)
if IsTeleporting or not data then return end
local hrp = getHRP()
if not hrp then return end
IsTeleporting = true
local fadeOut = TweenService:Create(
FadeFrame,
TweenInfo.new(CONFIG.TeleportFadeTime, Enum.EasingStyle.Sine, Enum.EasingDirection.Out),
{ BackgroundTransparency = 0 }
)
fadeOut:Play()
fadeOut.Completed:Wait()
local hrpNow = getHRP() -- character might've reset mid fade, check again
if hrpNow then
local safePosition = findSafeLandingPosition(data.Position)
hrpNow.CFrame = CFrame.new(safePosition)
end
task.wait(0.1)
local fadeIn = TweenService:Create(
FadeFrame,
TweenInfo.new(CONFIG.TeleportFadeTime, Enum.EasingStyle.Sine, Enum.EasingDirection.In),
{ BackgroundTransparency = 1 }
)
fadeIn:Play()
fadeIn.Completed:Wait()
IsTeleporting = false
end
-- ui time
local Window = Rayfield:CreateWindow({
Name = "Reincarnation Teleportation",
LoadingTitle = "Reincarnation Teleportation",
LoadingSubtitle = "Waypoint Beacon System",
ConfigurationSaving = { Enabled = false },
})
local Tab = Window:CreateTab("Waypoints", 4483362458)
Tab:CreateSection("Create")
Tab:CreateButton({
Name = "Place Waypoint Here",
Callback = placeWaypoint,
})
Tab:CreateSection("Manage")
local Dropdown = Tab:CreateDropdown({
Name = "Select Waypoint",
Options = {},
CurrentOption = {},
MultipleOptions = false,
Callback = function(option)
local name = option
if type(option) == "table" then
name = option[1]
end
SelectedWaypoint = findWaypointByName(name)
end,
})
RefreshDropdown = function(selectName)
-- closest first so the list actually stays useful once u have a bunch
local sorted = table.clone(Waypoints)
local hrp = getHRP()
if hrp then
table.sort(sorted, function(a, b)
return (hrp.Position - a.Position).Magnitude < (hrp.Position - b.Position).Magnitude
end)
end
local names = {}
for _, wp in ipairs(sorted) do
table.insert(names, wp.Name)
end
if Dropdown.Refresh then
Dropdown:Refresh(names, true)
elseif Dropdown.Set then
Dropdown:Set(names)
end
if selectName and Dropdown.Set then
Dropdown:Set(selectName)
end
end
local DistanceLabel = Tab:CreateLabel("Distance: —")
Tab:CreateButton({
Name = "Teleport to Selected",
Callback = function()
if IsTeleporting then return end
if SelectedWaypoint then
task.spawn(teleportTo, SelectedWaypoint)
else
Rayfield:Notify({ Title = "Reincarnation Teleportation", Content = "nothing selected", Duration = 3 })
end
end,
})
Tab:CreateInput({
Name = "Rename Selected Waypoint",
PlaceholderText = "new name...",
RemoveTextAfterFocusLost = true,
Callback = function(text)
if SelectedWaypoint then
renameWaypoint(SelectedWaypoint, text)
else
Rayfield:Notify({ Title = "Reincarnation Teleportation", Content = "nothing selected", Duration = 3 })
end
end,
})
Tab:CreateButton({
Name = "Delete Selected Waypoint",
Callback = function()
if SelectedWaypoint then
removeWaypoint(SelectedWaypoint)
else
Rayfield:Notify({ Title = "Reincarnation Teleportation", Content = "nothing selected", Duration = 3 })
end
end,
})
Tab:CreateSection("Settings")
local DEFAULT_SHOW_BEAMS = true
local DEFAULT_FADE_TIME = 0.5
local BeamsToggle
BeamsToggle = Tab:CreateToggle({
Name = "Show Beams",
CurrentValue = DEFAULT_SHOW_BEAMS,
Callback = function(value)
CONFIG.ShowBeams = value
for _, wp in ipairs(Waypoints) do
wp.Beam.Enabled = value
wp.Billboard.Enabled = value
wp.Sparkles.Enabled = value
wp.Marker.Transparency = value and 0 or 1
end
end,
})
local FadeSlider
FadeSlider = Tab:CreateSlider({
Name = "Teleport Fade Time (Default: 0.5s)",
Range = { 0.1, 2 },
Increment = 0.1,
Suffix = "s",
CurrentValue = DEFAULT_FADE_TIME,
Callback = function(value)
CONFIG.TeleportFadeTime = value
end,
})
Tab:CreateButton({
Name = "Reset Settings to Default",
Callback = function()
CONFIG.ShowBeams = DEFAULT_SHOW_BEAMS
CONFIG.TeleportFadeTime = DEFAULT_FADE_TIME
for _, wp in ipairs(Waypoints) do
wp.Beam.Enabled = DEFAULT_SHOW_BEAMS
wp.Billboard.Enabled = DEFAULT_SHOW_BEAMS
wp.Sparkles.Enabled = DEFAULT_SHOW_BEAMS
wp.Marker.Transparency = DEFAULT_SHOW_BEAMS and 0 or 1
end
if BeamsToggle.Set then BeamsToggle:Set(DEFAULT_SHOW_BEAMS) end
if FadeSlider.Set then FadeSlider:Set(DEFAULT_FADE_TIME) end
Rayfield:Notify({ Title = "Reincarnation Teleportation", Content = "settings reset (fade time back to 0.5s)", Duration = 3 })
end,
})
-- distance labels update every ~0.2s, no need to do it every single frame
local accumulated = 0
local UPDATE_INTERVAL = 0.2
RunService.Heartbeat:Connect(function(dt)
accumulated += dt
if accumulated < UPDATE_INTERVAL then return end
accumulated = 0
local hrp = getHRP()
if not hrp then return end
for _, wp in ipairs(Waypoints) do
local dist = (hrp.Position - wp.Position).Magnitude
wp.DistanceLabel.Text = string.format("%d studs", math.floor(dist))
end
if SelectedWaypoint then
local dist = (hrp.Position - SelectedWaypoint.Position).Magnitude
DistanceLabel:Set("Distance: " .. math.floor(dist) .. " studs (" .. SelectedWaypoint.Name .. ")")
else
DistanceLabel:Set("Distance: —")
end
end)
-- compass tho needs to run every frame or it'll look choppy when u spin the camera
RunService.RenderStepped:Connect(updateCompass)



.
.