Dragon ball and item locator
Key Required

Dragon ball and item locator

[ROF SAGA] Dragon Generationsmcguffer20mcguffer20 1.3K views 979 executesUpdated Mar 21, 2026
3.8/ 5(4 votes)
3175% Positive
Lua Script•503 lines (18034 chars)
-- LocalScript inside StarterPlayerScripts
-- Requires Rayfield: https://sirius.menu/rayfield

local Rayfield = loadstring(game:HttpGet('https://sirius.menu/rayfield'))()
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")

local player = Players.LocalPlayer
local camera = workspace.CurrentCamera
local character = player.Character or player.CharacterAdded:Wait()
local rootPart = character:WaitForChild("HumanoidRootPart")

-- ============================================================
-- ITEM CONFIG
-- ============================================================
local TRACKED_ITEMS = {
    { match = "exact", pattern = "Satellite",            color = Color3.fromRGB(0, 200, 255)   },
    { match = "exact", pattern = "Particle Accelerator", color = Color3.fromRGB(0, 255, 180)   },
    { match = "exact", pattern = "Carbon Wires",         color = Color3.fromRGB(150, 150, 150) },
    { match = "exact", pattern = "Wandering Earthling",  color = Color3.fromRGB(255, 255, 100) },
    { match = "exact", pattern = "Joy Boy",              color = Color3.fromRGB(255, 80, 80)   },
    { match = "exact", pattern = "Transistor",           color = Color3.fromRGB(100, 100, 255) },
    { match = "exact", pattern = "Nanite",               color = Color3.fromRGB(0, 255, 255)   },
    { match = "exact", pattern = "Toki Toki Egg",        color = Color3.fromRGB(255, 200, 255) },
    { match = "exact", pattern = "Time Ring",            color = Color3.fromRGB(200, 255, 200) },
    { match = "exact", pattern = "Buu Gum Pieces",       color = Color3.fromRGB(255, 100, 200) },
    { match = "exact", pattern = "Frieza Tail",          color = Color3.fromRGB(220, 180, 255) },
    { match = "exact", pattern = "Dragon Tooth",         color = Color3.fromRGB(200, 255, 100) },
    { match = "exact", pattern = "Dragon Fin",           color = Color3.fromRGB(100, 255, 150) },
    { match = "exact", pattern = "Omega Shenron Spike",  color = Color3.fromRGB(180, 50, 50)   },
}

-- ============================================================
-- NPC CONFIG
-- ============================================================
local TRACKED_NPCS = {
    { pattern = "Shady Salesman", color = Color3.fromRGB(0, 255, 100) },
}

local CLOSE_DISTANCE = 200

-- ============================================================
-- Random ID detector
-- ============================================================
local function isRandomID(name)
    return #name >= 8 and name:match("^[0-9a-fA-F]+$") ~= nil
end

local function getItemMatch(name)
    for _, entry in ipairs(TRACKED_ITEMS) do
        if entry.match == "exact" and name == entry.pattern then
            return entry.color, false
        elseif entry.match == "contains" and name:lower():find(entry.pattern:lower(), 1, true) then
            return entry.color, false
        end
    end
    if isRandomID(name) then
        return Color3.fromRGB(255, 165, 0), true
    end
    return nil, false
end

local function getNPCMatch(name)
    for _, entry in ipairs(TRACKED_NPCS) do
        if name:lower():find(entry.pattern:lower(), 1, true) then
            return entry.color
        end
    end
    return nil
end

local function isValid(obj)
    return obj:IsA("BasePart") or obj:IsA("Model")
end

local function getBasePart(obj)
    if obj:IsA("BasePart") then return obj end
    if obj:IsA("Model") then return obj.PrimaryPart or obj:FindFirstChildWhichIsA("BasePart") end
    return nil
end

-- ============================================================
-- Screen GUI — cursor fix applied
-- ============================================================
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "ItemLocatorHUD"
screenGui.ResetOnSpawn = false
screenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
screenGui.DisplayOrder = -1
screenGui.Parent = player.PlayerGui

-- Ensure mouse is never eaten by this GUI
UserInputService.MouseIconEnabled = true

-- ============================================================
-- Rayfield Window
-- ============================================================
local Window = Rayfield:CreateWindow({
    Name = "Item Locator",
    LoadingTitle = "Item Locator",
    LoadingSubtitle = "Spawn Tracker",
    Theme = "Default",
    DisableRayfieldPrompts = true,
    KeySystem = false,
})

local ItemTab = Window:CreateTab("Item Locator", "map-pin")
local NPCTab = Window:CreateTab("NPC Finder", "user")

-- ============================================================
-- State
-- ============================================================
local activeItems = {}
local activeNPCs = {}
local itemConnections = {}
local npcConnections = {}
local itemWorkspaceConn = nil
local npcWorkspaceConn = nil
local locatingEnabled = false
local npcFinderEnabled = false
local dragonBallFinderEnabled = false
local updateConnection = nil

-- ============================================================
-- Arrow builder
-- ============================================================
local function createArrow(color)
    local frame = Instance.new("Frame")
    frame.Size = UDim2.new(0, 140, 0, 28)
    frame.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
    frame.BackgroundTransparency = 0.35
    frame.BorderSizePixel = 0
    frame.Visible = false
    frame.Active = false
    frame.Parent = screenGui

    local corner = Instance.new("UICorner")
    corner.CornerRadius = UDim.new(0, 4)
    corner.Parent = frame

    local label = Instance.new("TextLabel")
    label.Size = UDim2.new(1, -28, 1, 0)
    label.Position = UDim2.new(0, 4, 0, 0)
    label.BackgroundTransparency = 1
    label.TextColor3 = color
    label.TextStrokeTransparency = 0
    label.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
    label.TextScaled = true
    label.Font = Enum.Font.GothamBold
    label.Text = ""
    label.Parent = frame

    local arrow = Instance.new("TextLabel")
    arrow.Size = UDim2.new(0, 24, 1, 0)
    arrow.Position = UDim2.new(1, -26, 0, 0)
    arrow.BackgroundTransparency = 1
    arrow.TextColor3 = color
    arrow.TextScaled = true
    arrow.Font = Enum.Font.GothamBold
    arrow.Text = "▶"
    arrow.Parent = frame

    return { frame = frame, label = label, arrow = arrow }
end

-- ============================================================
-- World visuals
-- ============================================================
local function createWorldVisuals(obj, color, labelText)
    local basePart = getBasePart(obj)
    if not basePart or not rootPart then return nil, nil, nil, nil, nil end

    local selBox = Instance.new("SelectionBox")
    selBox.Adornee = basePart
    selBox.Color3 = color
    selBox.LineThickness = 0.06
    selBox.SurfaceTransparency = 0.6
    selBox.SurfaceColor3 = color
    selBox.Parent = workspace

    local billboard = Instance.new("BillboardGui")
    billboard.Adornee = basePart
    billboard.AlwaysOnTop = true
    billboard.MaxDistance = CLOSE_DISTANCE
    billboard.Size = UDim2.new(0, 220, 0, 40)
    billboard.StudsOffset = Vector3.new(0, 5, 0)
    billboard.Parent = basePart

    local bg = Instance.new("Frame")
    bg.Size = UDim2.new(1, 0, 1, 0)
    bg.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
    bg.BackgroundTransparency = 0.4
    bg.BorderSizePixel = 0
    bg.Parent = billboard

    local textLabel = Instance.new("TextLabel")
    textLabel.Size = UDim2.new(1, 0, 1, 0)
    textLabel.BackgroundTransparency = 1
    textLabel.TextColor3 = color
    textLabel.TextStrokeTransparency = 0
    textLabel.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
    textLabel.Text = labelText
    textLabel.TextScaled = true
    textLabel.Font = Enum.Font.GothamBold
    textLabel.Parent = bg

    local a0 = Instance.new("Attachment")
    a0.Parent = rootPart

    local a1 = Instance.new("Attachment")
    a1.Parent = basePart

    local beam = Instance.new("Beam")
    beam.Attachment0 = a0
    beam.Attachment1 = a1
    beam.Color = ColorSequence.new(color)
    beam.Width0 = 0.12
    beam.Width1 = 0.12
    beam.FaceCamera = true
    beam.Transparency = NumberSequence.new(0.35)
    beam.Parent = workspace

    return selBox, billboard, beam, a0, a1
end

-- ============================================================
-- Update arrow position
-- ============================================================
local function updateArrow(obj, data, displayName)
    local basePart = getBasePart(obj)
    if not basePart or not rootPart then return end

    local dist = (basePart.Position - rootPart.Position).Magnitude
    local isClose = dist <= CLOSE_DISTANCE

    if data.beam then data.beam.Enabled = isClose end

    local arrowData = data.arrow
    if not arrowData then return end

    if isClose then
        arrowData.frame.Visible = false
        return
    end

    arrowData.frame.Visible = true
    arrowData.label.Text = displayName .. " [" .. math.floor(dist) .. "]"

    local screenPos, onScreen = camera:WorldToViewportPoint(basePart.Position)
    local vp = camera.ViewportSize
    local margin = 60

    if onScreen and screenPos.Z > 0 then
        local sx = math.clamp(screenPos.X, margin, vp.X - margin)
        local sy = math.clamp(screenPos.Y, margin, vp.Y - margin)
        arrowData.frame.Position = UDim2.new(0, sx - 70, 0, sy - 14)
        arrowData.arrow.Text = "●"
    else
        local cx, cy = vp.X / 2, vp.Y / 2
        local dx, dy = screenPos.X - cx, screenPos.Y - cy
        if screenPos.Z < 0 then dx, dy = -dx, -dy end

        local angle = math.atan2(dy, dx)
        local cos, sin = math.cos(angle), math.sin(angle)
        local scaleX = (vp.X / 2 - margin) / math.abs(cos)
        local scaleY = (vp.Y / 2 - margin) / math.abs(sin)
        local scale = math.min(scaleX, scaleY)

        local ex = math.clamp(cx + cos * scale, margin, vp.X - margin - 140)
        local ey = math.clamp(cy + sin * scale, margin, vp.Y - margin - 28)
        arrowData.frame.Position = UDim2.new(0, ex, 0, ey)

        local deg = math.deg(angle)
        if deg > -45 and deg <= 45 then arrowData.arrow.Text = "▶"
        elseif deg > 45 and deg <= 135 then arrowData.arrow.Text = "▼"
        elseif deg > 135 or deg <= -135 then arrowData.arrow.Text = "◀"
        else arrowData.arrow.Text = "▲" end
    end
end

-- ============================================================
-- Clear helpers
-- ============================================================
local function clearVisuals(data)
    pcall(function() data.selBox:Destroy() end)
    pcall(function() data.billboard:Destroy() end)
    pcall(function() data.beam:Destroy() end)
    pcall(function() data.a0:Destroy() end)
    pcall(function() data.a1:Destroy() end)
    if data.arrow then pcall(function() data.arrow.frame:Destroy() end) end
end

local function clearAllItems()
    for _, data in pairs(activeItems) do clearVisuals(data) end
    activeItems = {}
end

local function clearAllNPCs()
    for _, data in pairs(activeNPCs) do clearVisuals(data) end
    activeNPCs = {}
end

-- ============================================================
-- Register helpers
-- ============================================================
local function registerItem(obj, color, isDragonBall)
    if activeItems[obj] then return end
    local label = isDragonBall and "🐉 Dragon Ball" or obj.Name
    local selBox, billboard, beam, a0, a1 = createWorldVisuals(obj, color, label)
    local arrowData = createArrow(color)
    activeItems[obj] = {
        color = color, isDragonBall = isDragonBall,
        selBox = selBox, billboard = billboard,
        beam = beam, a0 = a0, a1 = a1,
        arrow = arrowData, label = label,
    }
end

local function registerNPC(obj, color)
    if activeNPCs[obj] then return end
    local label = "👤 " .. obj.Name
    local selBox, billboard, beam, a0, a1 = createWorldVisuals(obj, color, label)
    local arrowData = createArrow(color)
    activeNPCs[obj] = {
        color = color,
        selBox = selBox, billboard = billboard,
        beam = beam, a0 = a0, a1 = a1,
        arrow = arrowData, label = label,
    }
end

-- ============================================================
-- Watchers
-- ============================================================
local function watchItem(obj)
    if not isValid(obj) then return end
    if activeItems[obj] then return end
    local color, isDragonBall = getItemMatch(obj.Name)
    if isDragonBall and not dragonBallFinderEnabled then return end
    if not color then return end
    registerItem(obj, color, isDragonBall)
    local conn = obj.AncestryChanged:Connect(function(_, parent)
        if not parent then
            if activeItems[obj] then clearVisuals(activeItems[obj]); activeItems[obj] = nil end
            if itemConnections[obj] then itemConnections[obj]:Disconnect(); itemConnections[obj] = nil end
        end
    end)
    itemConnections[obj] = conn
end

local function watchNPC(obj)
    if not obj:IsA("Model") then return end
    if activeNPCs[obj] then return end
    local color = getNPCMatch(obj.Name)
    if not color then return end
    local humanoid = obj:FindFirstChildWhichIsA("Humanoid")
    if not humanoid then return end
    registerNPC(obj, color)
    local conn = obj.AncestryChanged:Connect(function(_, parent)
        if not parent then
            if activeNPCs[obj] then clearVisuals(activeNPCs[obj]); activeNPCs[obj] = nil end
            if npcConnections[obj] then npcConnections[obj]:Disconnect(); npcConnections[obj] = nil end
        end
    end)
    npcConnections[obj] = conn
end

-- ============================================================
-- Start / Stop
-- ============================================================
local function startItemTracking()
    for _, obj in ipairs(workspace:GetDescendants()) do watchItem(obj) end
    itemWorkspaceConn = workspace.DescendantAdded:Connect(function(obj)
        if locatingEnabled then watchItem(obj) end
    end)
end

local function stopItemTracking()
    if itemWorkspaceConn then itemWorkspaceConn:Disconnect(); itemWorkspaceConn = nil end
    for _, conn in pairs(itemConnections) do conn:Disconnect() end
    itemConnections = {}
    clearAllItems()
end

local function startNPCTracking()
    for _, obj in ipairs(workspace:GetDescendants()) do watchNPC(obj) end
    npcWorkspaceConn = workspace.DescendantAdded:Connect(function(obj)
        if npcFinderEnabled then
            task.delay(0.5, function() watchNPC(obj) end)
        end
    end)
end

local function stopNPCTracking()
    if npcWorkspaceConn then npcWorkspaceConn:Disconnect(); npcWorkspaceConn = nil end
    for _, conn in pairs(npcConnections) do conn:Disconnect() end
    npcConnections = {}
    clearAllNPCs()
end

local function startUpdateLoop()
    if updateConnection then return end
    updateConnection = RunService.Heartbeat:Connect(function()
        -- Keep cursor enabled every frame just in case
        UserInputService.MouseIconEnabled = true

        character = player.Character
        if not character then return end
        rootPart = character:FindFirstChild("HumanoidRootPart")
        if not rootPart then return end

        if locatingEnabled then
            for obj, data in pairs(activeItems) do
                if obj and obj.Parent then
                    updateArrow(obj, data, data.label)
                else
                    clearVisuals(data); activeItems[obj] = nil
                end
            end
        end

        if npcFinderEnabled then
            for obj, data in pairs(activeNPCs) do
                if obj and obj.Parent then
                    updateArrow(obj, data, data.label)
                else
                    clearVisuals(data); activeNPCs[obj] = nil
                end
            end
        end
    end)
end

local function stopUpdateLoop()
    if updateConnection then updateConnection:Disconnect(); updateConnection = nil end
end

-- ============================================================
-- Rayfield UI — Item Tab
-- ============================================================
ItemTab:CreateToggle({
    Name = "Enable Item Locator",
    CurrentValue = false,
    Flag = "LocatorToggle",
    Callback = function(value)
        locatingEnabled = value
        if value then
            character = player.Character or player.CharacterAdded:Wait()
            rootPart = character:WaitForChild("HumanoidRootPart")
            startItemTracking()
            startUpdateLoop()
        else
            stopItemTracking()
            if not npcFinderEnabled then stopUpdateLoop() end
        end
    end,
})

ItemTab:CreateDivider()

ItemTab:CreateToggle({
    Name = "Dragon Ball Finder",
    CurrentValue = false,
    Flag = "DragonBallFinder",
    Callback = function(value)
        dragonBallFinderEnabled = value
        if locatingEnabled and value then
            for _, obj in ipairs(workspace:GetDescendants()) do watchItem(obj) end
        end
    end,
})

ItemTab:CreateLabel("Close range: floating label + beam")
ItemTab:CreateLabel("Far range: screen edge arrow + distance")
ItemTab:CreateLabel("🟠 Orange = Dragon Balls (Dragon Ball Finder)")

-- ============================================================
-- Rayfield UI — NPC Tab
-- ============================================================
NPCTab:CreateToggle({
    Name = "Enable NPC Finder",
    CurrentValue = false,
    Flag = "NPCFinder",
    Callback = function(value)
        npcFinderEnabled = value
        if value then
            character = player.Character or player.CharacterAdded:Wait()
            rootPart = character:WaitForChild("HumanoidRootPart")
            startNPCTracking()
            startUpdateLoop()
        else
            stopNPCTracking()
            if not locatingEnabled then stopUpdateLoop() end
        end
    end,
})

NPCTab:CreateLabel("Tracked NPCs:")
NPCTab:CreateLabel("🟢 Shady Salesman")
NPCTab:CreateLabel("Detects NPCs using their Humanoid.")
NPCTab:CreateLabel("Close range: floating label + beam")
NPCTab:CreateLabel("Far range: screen edge arrow + distance")

Features & Information

Highlights and locate dragon balls and items that you need to find for you paths
#made with ai#ai#FREE#DRAGON BALL

Community Comments (3)

mcguffer20mcguffer20Mar 21, 2026

Made with ai so its not perfect. Open source, do what you will with it.

SagemenosSagemenosApr 28, 2026

Can it locate the toki toki egg

Replying to @Sagemenos
mcguffer20mcguffer20May 4, 2026

@Sagemenos think so

More Scripts for [ROF SAGA] Dragon Generations