CHASER AND KEY ESP
Keyless Verified

CHASER AND KEY ESP

[UPD 2] THRESHOLD ShrakBloxShrakBlox 391 views 362 executesUpdated Oct 7, 2026
Unrated
00
Lua Script•574 lines (13246 chars)
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")

local localPlayer = Players.LocalPlayer
local playerGui = localPlayer:WaitForChild("PlayerGui")

local keySources = {
	{ "ChaseWorld", "KeySpawns" },
	{ "ChaseSpots", "KeySpawns" },
}

local monsterList = {
	{
		Name = "ELI",
		Path = { "ChaseWorld", "Eli" },
		AnchorParts = { "Eli_Torso", "Eli_Head" },
		StateAttribute = "EliState",
		ChaseStates = { CHASE = true, HUNT = true, STALK = true, KILL = true },
		Color = Color3.fromRGB(255, 60, 60),
	},
	{
		Name = "TWIN",
		Path = { "TwinEntity" },
		AnchorParts = { "Root" },
		StateAttribute = "State",
		ChaseStates = { chase = true, hunt = true, kill = true },
		Color = Color3.fromRGB(255, 90, 200),
	},
	{
		Name = "SCROW",
		Path = { "Scrow" },
		AnchorParts = { "Root" },
		StateAttribute = "State",
		ChaseStates = { chase = true, hunt = true },
		Color = Color3.fromRGB(180, 120, 255),
	},
}

local monitorDistance = 60
local minActiveHeight = -50
local maxDrawDistance = 3000
local keyColor = Color3.fromRGB(255, 170, 0)
local keyLabelColor = Color3.fromRGB(255, 205, 90)
local arrowGlyph = "\226\158\156"

local keyModels = {}
local monsterModels = {}
local connections = {}
local espOn = true
local unloaded = false

local function walkPath(root, path)
	local node = root
	for _, segment in ipairs(path) do
		if node == nil then
			return nil
		end
		node = node:FindFirstChild(segment)
	end
	return node
end

local function getKeyPosition(model)
	local point = model:FindFirstChild("KeyPoint", true)
	if point and point:IsA("Attachment") then
		return point.WorldPosition
	end

	local mesh = model:FindFirstChild("KEY__key")
	if mesh and mesh:IsA("BasePart") then
		return mesh.Position
	end

	for _, d in ipairs(model:GetDescendants()) do
		if d:IsA("BasePart") then
			return d.Position
		end
	end

	return nil
end

local function getMonsterPosition(model, anchorParts)
	for _, partName in ipairs(anchorParts) do
		local part = model:FindFirstChild(partName, true)
		if part and part:IsA("BasePart") then
			return part.Position
		end
	end

	for _, d in ipairs(model:GetDescendants()) do
		if d:IsA("BasePart") and d.Transparency < 1 then
			return d.Position
		end
	end

	local root = model:FindFirstChild("RootPart") or model:FindFirstChild("Root")
	if root and root:IsA("BasePart") then
		return root.Position
	end

	return nil
end

local function distanceFromPlayer(position)
	if position == nil then
		return nil
	end

	local character = localPlayer.Character
	local root = character and character:FindFirstChild("HumanoidRootPart")
	if root then
		return (root.Position - position).Magnitude
	end

	local camera = Workspace.CurrentCamera
	if camera then
		return (camera.CFrame.Position - position).Magnitude
	end

	return nil
end

local function readState(model, spec)
	if not spec.StateAttribute then
		return nil
	end

	local ok, value = pcall(function()
		return model:GetAttribute(spec.StateAttribute)
	end)

	if ok and value ~= nil then
		return tostring(value)
	end

	return nil
end

local function isChasingState(state, spec)
	if not state then
		return false
	end

	local upper = string.upper(state)
	for chaseState in pairs(spec.ChaseStates) do
		if upper == string.upper(chaseState) then
			return true
		end
	end

	return false
end

local function buildArrow(color)
	local arrow = Instance.new("TextLabel")
	arrow.Name = "espArrow"
	arrow.AnchorPoint = Vector2.new(0.5, 0.5)
	arrow.BackgroundTransparency = 1
	arrow.Size = UDim2.fromOffset(64, 64)
	arrow.Font = Enum.Font.GothamBlack
	arrow.TextSize = 46
	arrow.TextColor3 = color
	arrow.TextStrokeTransparency = 0
	arrow.TextStrokeColor3 = Color3.new(0, 0, 0)
	arrow.Text = arrowGlyph
	arrow.Visible = false
	arrow.Parent = playerGui
	return arrow
end

local function updateArrow(arrow, position, color)
	local camera = Workspace.CurrentCamera
	if not camera then
		return
	end

	local viewport = camera.ViewportSize
	if viewport.X <= 0 or viewport.Y <= 0 then
		return
	end

	local screenPoint, onScreen = camera:WorldToViewportPoint(position)

	if onScreen and screenPoint.Z > 0 then
		local clampedX = math.clamp(screenPoint.X, 48, viewport.X - 48)
		local clampedY = math.clamp(screenPoint.Y, 48, viewport.Y - 48)

		if clampedX == screenPoint.X and clampedY == screenPoint.Y then
			arrow.Visible = false
			return
		end

		arrow.Position = UDim2.fromOffset(clampedX, clampedY)
	else
		local relative = camera.CFrame:PointToObjectSpace(position)
		local flat = Vector2.new(relative.X, relative.Y)

		if flat.Magnitude < 1e-4 then
			flat = Vector2.new(0, 1)
		else
			flat = flat.Unit
		end

		if relative.Z > 0 then
			flat = -flat
		end

		local halfX = viewport.X / 2
		local halfY = viewport.Y / 2
		local scale = math.min(
			halfX / math.max(math.abs(flat.X), 1e-4),
			halfY / math.max(math.abs(flat.Y), 1e-4)
		)

		local projectedX = halfX + flat.X * scale
		local projectedY = halfY - flat.Y * scale

		arrow.Position = UDim2.fromOffset(
			math.clamp(projectedX, 48, viewport.X - 48),
			math.clamp(projectedY, 48, viewport.Y - 48)
		)
	end

	arrow.TextColor3 = color
	arrow.Visible = true
end

local function buildKeyEsp(model)
	if getKeyPosition(model) == nil then
		return nil
	end

	local highlight = Instance.new("Highlight")
	highlight.Name = "keyEspHighlight"
	highlight.Adornee = model
	highlight.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
	highlight.FillColor = keyColor
	highlight.FillTransparency = 0.65
	highlight.OutlineColor = keyColor
	highlight.OutlineTransparency = 0
	highlight.Parent = model

	local gui = Instance.new("BillboardGui")
	gui.Name = "keyEspLabel"
	gui.Adornee = model
	gui.AlwaysOnTop = true
	gui.LightInfluence = 0
	gui.Size = UDim2.fromOffset(150, 22)
	gui.StudsOffsetWorldSpace = Vector3.new(0, 1.6, 0)
	gui.MaxDistance = maxDrawDistance
	gui.Parent = model

	local label = Instance.new("TextLabel")
	label.Name = "Text"
	label.BackgroundTransparency = 1
	label.Size = UDim2.fromScale(1, 1)
	label.Font = Enum.Font.GothamBold
	label.TextSize = 14
	label.TextColor3 = keyLabelColor
	label.TextStrokeTransparency = 0
	label.TextStrokeColor3 = Color3.new(0, 0, 0)
	label.Text = "KEY"
	label.Parent = gui

	return {
		Model = model,
		Highlight = highlight,
		Gui = gui,
		Label = label,
		Arrow = buildArrow(keyColor),
	}
end

local function buildMonsterEsp(model, spec)
	if getMonsterPosition(model, spec.AnchorParts) == nil then
		return nil
	end

	local highlight = Instance.new("Highlight")
	highlight.Name = "monsterEspHighlight"
	highlight.Adornee = model
	highlight.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
	highlight.FillColor = spec.Color
	highlight.FillTransparency = 0.85
	highlight.OutlineColor = spec.Color
	highlight.OutlineTransparency = 0
	highlight.Parent = model

	local gui = Instance.new("BillboardGui")
	gui.Name = "monsterEspLabel"
	gui.Adornee = model
	gui.AlwaysOnTop = true
	gui.LightInfluence = 0
	gui.Size = UDim2.fromOffset(190, 40)
	gui.StudsOffsetWorldSpace = Vector3.new(0, 3.4, 0)
	gui.MaxDistance = maxDrawDistance
	gui.Parent = model

	local title = Instance.new("TextLabel")
	title.Name = "Title"
	title.BackgroundTransparency = 1
	title.Size = UDim2.new(1, 0, 0.6, 0)
	title.Font = Enum.Font.GothamBlack
	title.TextSize = 17
	title.TextColor3 = spec.Color
	title.TextStrokeTransparency = 0
	title.TextStrokeColor3 = Color3.new(0, 0, 0)
	title.Text = spec.Name
	title.Parent = gui

	local subtitle = Instance.new("TextLabel")
	subtitle.Name = "Subtitle"
	subtitle.BackgroundTransparency = 1
	subtitle.Position = UDim2.new(0, 0, 0.58, 0)
	subtitle.Size = UDim2.new(1, 0, 0.42, 0)
	subtitle.Font = Enum.Font.GothamBold
	subtitle.TextSize = 13
	subtitle.TextColor3 = Color3.fromRGB(255, 235, 235)
	subtitle.TextStrokeTransparency = 0
	subtitle.TextStrokeColor3 = Color3.new(0, 0, 0)
	subtitle.Text = ""
	subtitle.Parent = gui

	return {
		Model = model,
		Spec = spec,
		Highlight = highlight,
		Gui = gui,
		Title = title,
		Subtitle = subtitle,
		Arrow = buildArrow(spec.Color),
	}
end

local function destroyEntry(entry)
	for _, inst in ipairs({ entry.Highlight, entry.Gui, entry.Arrow }) do
		if inst then
			inst:Destroy()
		end
	end
end

local function collectKeys()
	local found = {}

	for _, source in ipairs(keySources) do
		local container = walkPath(Workspace, source)
		if container then
			for _, child in ipairs(container:GetChildren()) do
				local key = child:FindFirstChild("Key")
				if key and key:IsA("Model") then
					table.insert(found, key)
				end
			end
		end
	end

	return found
end

local function collectMonsters()
	local found = {}

	for _, spec in ipairs(monsterList) do
		local model = walkPath(Workspace, spec.Path)
		if model and model.Parent then
			local position = getMonsterPosition(model, spec.AnchorParts)
			if position and position.Y > minActiveHeight then
				table.insert(found, { Model = model, Spec = spec })
			end
		end
	end

	return found
end

local function syncEsp()
	if unloaded then
		return
	end

	local liveKeys = {}
	for _, model in ipairs(collectKeys()) do
		liveKeys[model] = true
		if not keyModels[model] then
			local ok, entry = pcall(buildKeyEsp, model)
			if ok and entry then
				keyModels[model] = entry
			end
		end
	end

	for model, entry in pairs(keyModels) do
		if not liveKeys[model] or not model.Parent then
			destroyEntry(entry)
			keyModels[model] = nil
		end
	end

	local liveMonsters = {}
	for _, item in ipairs(collectMonsters()) do
		liveMonsters[item.Model] = item.Spec
		if not monsterModels[item.Model] then
			local ok, entry = pcall(buildMonsterEsp, item.Model, item.Spec)
			if ok and entry then
				monsterModels[item.Model] = entry
			end
		end
	end

	for model, entry in pairs(monsterModels) do
		if not liveMonsters[model] or not model.Parent then
			destroyEntry(entry)
			monsterModels[model] = nil
		end
	end
end

local function updateKeyEsp(entry)
	local position = getKeyPosition(entry.Model)
	if position == nil then
		return
	end

	local distance = distanceFromPlayer(position)
	if distance then
		entry.Label.Text = "KEY  " .. tostring(math.floor(distance + 0.5)) .. "m"
	end

	if entry.Arrow then
		updateArrow(entry.Arrow, position, keyColor)
	end
end

local function updateMonsterEsp(entry)
	local position = getMonsterPosition(entry.Model, entry.Spec.AnchorParts)
	if position == nil then
		return
	end

	local distance = distanceFromPlayer(position)
	local state = readState(entry.Model, entry.Spec)
	local chasing = isChasingState(state, entry.Spec)
	local close = distance ~= nil and distance <= monitorDistance

	local color = entry.Spec.Color
	if close then
		color = Color3.fromRGB(255, 0, 0)
	elseif chasing then
		color = Color3.fromRGB(255, 120, 0)
	end

	entry.Highlight.OutlineColor = color
	entry.Highlight.FillColor = color
	entry.Highlight.FillTransparency = close and 0.7 or 0.85
	entry.Title.TextColor3 = color
	entry.Title.Text = close and (entry.Spec.Name .. "  !!") or entry.Spec.Name

	local info = {}
	if state then
		table.insert(info, string.upper(state))
	end
	if distance then
		table.insert(info, tostring(math.floor(distance + 0.5)) .. "m")
	end
	if close then
		table.insert(info, "CLOSE")
	end
	entry.Subtitle.Text = table.concat(info, "  ")

	if entry.Arrow then
		updateArrow(entry.Arrow, position, color)
	end
end

local function setEspVisible(visible)
	espOn = visible

	for _, entry in pairs(keyModels) do
		entry.Highlight.Enabled = visible
		entry.Gui.Enabled = visible
		if not visible and entry.Arrow then
			entry.Arrow.Visible = false
		end
	end

	for _, entry in pairs(monsterModels) do
		entry.Highlight.Enabled = visible
		entry.Gui.Enabled = visible
		if not visible and entry.Arrow then
			entry.Arrow.Visible = false
		end
	end
end

local function unloadEsp()
	if unloaded then
		return
	end

	unloaded = true
	espOn = false

	for _, connection in ipairs(connections) do
		connection:Disconnect()
	end
	table.clear(connections)

	for model, entry in pairs(keyModels) do
		destroyEntry(entry)
		keyModels[model] = nil
	end

	for model, entry in pairs(monsterModels) do
		destroyEntry(entry)
		monsterModels[model] = nil
	end
end

table.insert(connections, Workspace.DescendantAdded:Connect(function()
	task.defer(syncEsp)
end))

table.insert(connections, Workspace.DescendantRemoving:Connect(function()
	task.defer(syncEsp)
end))

table.insert(connections, RunService.RenderStepped:Connect(function()
	if unloaded then
		return
	end

	for model, entry in pairs(keyModels) do
		if model.Parent then
			pcall(updateKeyEsp, entry)
		else
			destroyEntry(entry)
			keyModels[model] = nil
		end
	end

	for model, entry in pairs(monsterModels) do
		if model.Parent then
			pcall(updateMonsterEsp, entry)
		else
			destroyEntry(entry)
			monsterModels[model] = nil
		end
	end
end))

table.insert(connections, UserInputService.InputBegan:Connect(function(input, processed)
	if processed or unloaded then
		return
	end

	if input.KeyCode == Enum.KeyCode.RightShift then
		setEspVisible(not espOn)
	elseif input.KeyCode == Enum.KeyCode.RightControl then
		unloadEsp()
	end
end))

task.spawn(function()
	while not unloaded do
		task.wait(0.75)
		pcall(syncEsp)
	end
end)

syncEsp()

Features & Information

Key ESP Monster/Chaser ESP
#open source#esp#keyless#free#no key

Community Comments (0)

No comments yet for this script.