Smart Retroesque Click to Move BEST ON NDS
Key Required

Smart Retroesque Click to Move BEST ON NDS

Natural Disaster SurvivalKalanGamesYTKalanGamesYT 1.9K views 52 executesUpdated Jan 23, 2026
2.5/ 5(2 votes)
1150% Positive
Lua Script•184 lines (5127 chars)
local Players = game:GetService("Players")
local PathfindingService = game:GetService("PathfindingService")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")

local player = Players.LocalPlayer
local mouse = player:GetMouse()
local camera = Workspace.CurrentCamera

-- MARKER DISC
local marker = Instance.new("Part")
marker.Name = "ClickMarker"
marker.Anchored = true
marker.CanCollide = false
marker.Shape = Enum.PartType.Cylinder
marker.Size = Vector3.new(0.2, 2, 2)
marker.Material = Enum.Material.Plastic
marker.Color = Color3.fromRGB(0, 255, 0)
marker.Transparency = 0
marker.Orientation = Vector3.new(0, 0, 90)
marker.Parent = workspace
marker.Position = Vector3.new(0, -1000, 0)

-- CHARACTER
local character, humanoid, root
local moving = false
local pathID = 0

local function setupCharacter(char)
    character = char
    humanoid = char:WaitForChild("Humanoid")
    root = char:WaitForChild("HumanoidRootPart")

    humanoid:SetStateEnabled(Enum.HumanoidStateType.FallingDown, false)
    humanoid:SetStateEnabled(Enum.HumanoidStateType.Ragdoll, false)
    humanoid:SetStateEnabled(Enum.HumanoidStateType.Physics, false)

    pathID += 1
    moving = false
end

setupCharacter(player.Character or player.CharacterAdded:Wait())
player.CharacterAdded:Connect(setupCharacter)

-- RAYCAST PARAMS
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Blacklist

-- HIGHLIGHT
local currentHighlight = nil
local currentTarget = nil

local function clearHighlight()
    if currentHighlight then
        currentHighlight:Destroy()
        currentHighlight = nil
        currentTarget = nil
    end
end

local function createHighlight(character)
    clearHighlight()

    local highlight = Instance.new("Highlight")
    highlight.FillColor = Color3.fromRGB(0, 255, 0)
    highlight.FillTransparency = 0.6
    highlight.OutlineColor = Color3.fromRGB(0, 255, 0)
    highlight.OutlineTransparency = 0.2
    highlight.Parent = character

    currentHighlight = highlight
    currentTarget = character
end

-- HELPERS
local function isNeon(part)
    return part and part:IsA("BasePart") and part.Material == Enum.Material.Neon
end

local function getGroundPosition()
    if not character then return end
    params.FilterDescendantsInstances = { character }

    local unitRay = camera:ScreenPointToRay(mouse.X, mouse.Y)
    local hit = workspace:Raycast(unitRay.Origin, unitRay.Direction * 1000, params)
    if not hit then return end

    local downHit = workspace:Raycast(hit.Position + Vector3.new(0, 5, 0), Vector3.new(0, -500, 0), params)
    return downHit and downHit.Position
end

local function adjustWaypoint(wpPos)
    params.FilterDescendantsInstances = { character }
    local hit = workspace:Raycast(wpPos + Vector3.new(0, 5, 0), Vector3.new(0, -10, 0), params)

    if hit and isNeon(hit.Instance) then
        local offset = Vector3.new(3, 0, 0)
        local try1 = wpPos + offset
        local try2 = wpPos - offset

        local hit1 = workspace:Raycast(try1 + Vector3.new(0, 5, 0), Vector3.new(0, -10, 0), params)
        local hit2 = workspace:Raycast(try2 + Vector3.new(0, 5, 0), Vector3.new(0, -10, 0), params)

        if hit1 and not isNeon(hit1.Instance) then
            return hit1.Position
        elseif hit2 and not isNeon(hit2.Instance) then
            return hit2.Position
        end

        return wpPos + Vector3.new(0, 6, 0)
    end

    return wpPos
end

-- DISC FOLLOW
RunService.RenderStepped:Connect(function()
    if moving then return end
    local pos = getGroundPosition()
    if pos then
        marker.Position = pos + Vector3.new(0, 0.05, 0)
    end
end)

-- CLICK TO MOVE
mouse.Button1Down:Connect(function()
    if not humanoid or humanoid.Health <= 0 then return end

    local targetPos = getGroundPosition()
    if not targetPos then return end

    pathID += 1
    local myPathID = pathID
    moving = true

    marker.Position = targetPos + Vector3.new(0, 0.05, 0)

    local path = PathfindingService:CreatePath({
        AgentRadius = 2,
        AgentHeight = 5,
        AgentCanJump = true,
        AgentCanClimb = true
    })

    path:ComputeAsync(root.Position, targetPos)
    if path.Status ~= Enum.PathStatus.Success then
        moving = false
        return
    end

    for _, wp in ipairs(path:GetWaypoints()) do
        if myPathID ~= pathID then return end

        local pos = adjustWaypoint(wp.Position)

        if wp.Action == Enum.PathWaypointAction.Jump then
            humanoid.Jump = true
        end

        humanoid:MoveTo(pos)
        humanoid.MoveToFinished:Wait()
    end

    moving = false
end)

-- HIGHLIGHT TARGET
RunService.RenderStepped:Connect(function()
    local target = mouse.Target
    if not target or not target.Parent then
        clearHighlight()
        return
    end

    local targetPlayer = Players:GetPlayerFromCharacter(target.Parent)
    if not targetPlayer or targetPlayer == player then
        clearHighlight()
        return
    end

    if currentTarget ~= targetPlayer.Character then
        createHighlight(targetPlayer.Character)
    end
end)

Features & Information

Just pathfind

Community Comments (3)

KalanGamesYTKalanGamesYTJan 23, 2026

@Shadow69 and what if it's ai, it works. doesn't it?

KalanGamesYTKalanGamesYTJan 25, 2026

@Shadow69 im learning now shut up, i've probably been learning longer than yo ahh

KalanGamesYTKalanGamesYTJan 27, 2026

@Shadow69 nah

More Scripts for Natural Disaster Survival