-- NPC Hitbox Expander GUI — Works with most damage tools -- Modes: -- - Proxy: Adds a welded neon-red hitbox part (CanTouch/CanQuery = true) so weapons and raycasts register. -- - Resize: Resizes the real HRP, optionally tints neon red. Reverts cleanly on disable. -- Default size: 9, transparency: 0.4, mode: Proxy --// Services local Players = game:GetService("Players") local UserInputService = game:GetService("UserInputService") local CoreGui = game:GetService("CoreGui") --// Constants local GUI_NAME = "NPC_Hitbox_GUI" local PROXY_NAME = "NF_NPC_Hitbox" local TAG_ATTR = "NF_HitboxTag" local MODE_PROXY, MODE_RESIZE = "Proxy", "Resize" --// Cleanup previous UI local old = CoreGui:FindFirstChild(GUI_NAME) if old then old:Destroy() end --// State local enabled = false local currentSize = 9 local currentTransparency = 0.40 local mode = MODE_PROXY --// Helpers local function isNPC(model) if not (model and model:IsA("Model")) then return false end local hum = model:FindFirstChildOfClass("Humanoid") if not hum then return false end return Players:GetPlayerFromCharacter(model) == nil end local function getRoot(model) if not model then return nil end return model:FindFirstChild("HumanoidRootPart") or model:FindFirstChild("UpperTorso") or model:FindFirstChild("Torso") end -- Proxy hitbox: real touch/query, no collisions local function makeProxyHitbox(hrp, size, trans) local existing = hrp:FindFirstChild(PROXY_NAME) if existing and existing:IsA("BasePart") and existing:GetAttribute(TAG_ATTR) then existing.Size = Vector3.new(size, size, size) existing.Transparency = trans return existing end local part = Instance.new("Part") part.Name = PROXY_NAME part.Size = Vector3.new(size, size, size) part.Color = Color3.fromRGB(255, 0, 0) part.Material = Enum.Material.Neon part.Transparency = trans part.CanCollide = false -- no physical push part.CanTouch = true -- Touched events can fire on weapons part.CanQuery = true -- Raycasts and spatial queries will hit part.Massless = true part.CastShadow = false part.Anchored = false part.CFrame = hrp.CFrame part:SetAttribute(TAG_ATTR, true) part.Parent = hrp local weld = Instance.new("WeldConstraint") weld.Part0 = hrp weld.Part1 = part weld.Parent = part return part end -- Resize HRP: stores and restores original visuals/size local function storeOriginal(hrp) if hrp:GetAttribute("NF_Stored") then return end hrp:SetAttribute("NF_Stored", true) hrp:SetAttribute("NF_OrigSize", hrp.Size) hrp:SetAttribute("NF_OrigColor", hrp.Color) hrp:SetAttribute("NF_OrigMat", tostring(hrp.Material)) hrp:SetAttribute("NF_OrigTrans", hrp.Transparency) end local function applyResize(hrp, size, trans) storeOriginal(hrp) hrp.Size = Vector3.new(size, size, size) hrp.Color = Color3.fromRGB(255, 0, 0) hrp.Material = Enum.Material.Neon hrp.Transparency = trans -- Ensure tools/rays can see/touch HRP hrp.CanQuery = true hrp.CanTouch = true -- Leave CanCollide as-is to avoid breaking NPC physics end local function restoreResize(hrp) if not hrp:GetAttribute("NF_Stored") then return end local origSize = hrp:GetAttribute("NF_OrigSize") local origColor = hrp:GetAttribute("NF_OrigColor") local origMat = hrp:GetAttribute("NF_OrigMat") local origTrans = hrp:GetAttribute("NF_OrigTrans") if typeof(origSize) == "Vector3" then hrp.Size = origSize end if typeof(origColor) == "Color3" then hrp.Color = origColor end if typeof(origMat) == "string" and Enum.Material[origMat] then hrp.Material = Enum.Material[origMat] end if typeof(origTrans) == "number" then hrp.Transparency = origTrans end hrp:SetAttribute("NF_Stored", nil) hrp:SetAttribute("NF_OrigSize", nil) hrp:SetAttribute("NF_OrigColor", nil) hrp:SetAttribute("NF_OrigMat", nil) hrp:SetAttribute("NF_OrigTrans", nil) end local function applyToNPC(model, size, trans) local hrp = getRoot(model) if not hrp then return end if mode == MODE_PROXY then makeProxyHitbox(hrp, size, trans) else applyResize(hrp, size, trans) end end local function removeFromNPC(model) local hrp = getRoot(model) if not hrp then return end if mode == MODE_PROXY then local hb = hrp:FindFirstChild(PROXY_NAME) if hb and hb:IsA("BasePart") and hb:GetAttribute(TAG_ATTR) then hb:Destroy() end else restoreResize(hrp) end end local function applyAll(size, trans) for _, d in ipairs(workspace:GetDescendants()) do if d:IsA("Model") and isNPC(d) then applyToNPC(d, size, trans) end end end local function removeAll() for _, d in ipairs(workspace:GetDescendants()) do if d:IsA("Model") and isNPC(d) then removeFromNPC(d) end end end -- Auto-apply to new NPCs local descConn local function startAuto() if descConn then descConn:Disconnect() end descConn = workspace.DescendantAdded:Connect(function(obj) if not enabled then return end if obj:IsA("Humanoid") then local m = obj.Parent if isNPC(m) then local hrp = getRoot(m) if hrp then applyToNPC(m, currentSize, currentTransparency) end end elseif obj:IsA("BasePart") and (obj.Name == "HumanoidRootPart" or obj.Name == "UpperTorso" or obj.Name == "Torso") then local m = obj:FindFirstAncestorOfClass("Model") if isNPC(m) then applyToNPC(m, currentSize, currentTransparency) end end end) end local function stopAuto() if descConn then descConn:Disconnect() end descConn = nil end local function setEnabled(on) enabled = on if enabled then applyAll(currentSize, currentTransparency) startAuto() else stopAuto() removeAll() end end --// UI local ui = Instance.new("ScreenGui") ui.Name = GUI_NAME ui.ResetOnSpawn = false ui.IgnoreGuiInset = false ui.Parent = CoreGui local frame = Instance.new("Frame") frame.Name = "Main" frame.Size = UDim2.new(0, 320, 0, 200) frame.Position = UDim2.new(0, 40, 0, 120) frame.BackgroundColor3 = Color3.fromRGB(22, 22, 22) frame.BorderSizePixel = 0 frame.Parent = ui Instance.new("UICorner", frame).CornerRadius = UDim.new(0, 8) local title = Instance.new("TextLabel") title.Size = UDim2.new(1, -36, 0, 32) title.Position = UDim2.new(0, 12, 0, 8) title.BackgroundTransparency = 1 title.Text = "NPC Hitbox Expander (works)" title.TextColor3 = Color3.fromRGB(255, 255, 255) title.TextSize = 18 title.Font = Enum.Font.GothamBold title.TextXAlignment = Enum.TextXAlignment.Left title.Parent = frame local closeBtn = Instance.new("TextButton") closeBtn.Size = UDim2.new(0, 24, 0, 24) closeBtn.Position = UDim2.new(1, -32, 0, 10) closeBtn.BackgroundColor3 = Color3.fromRGB(40, 40, 40) closeBtn.Text = "×" closeBtn.TextColor3 = Color3.fromRGB(255, 255, 255) closeBtn.TextSize = 20 closeBtn.Font = Enum.Font.GothamBold closeBtn.Parent = frame Instance.new("UICorner", closeBtn).CornerRadius = UDim.new(1, 0) local status = Instance.new("TextLabel") status.Size = UDim2.new(1, -24, 0, 16) status.Position = UDim2.new(0, 12, 0, 36) status.BackgroundTransparency = 1 status.Text = "NPC-only • Neon red • Touch & Raycast enabled" status.TextColor3 = Color3.fromRGB(140, 140, 140) status.TextSize = 12 status.Font = Enum.Font.Gotham status.TextXAlignment = Enum.TextXAlignment.Left status.Parent = frame -- Size input local sizeLabel = Instance.new("TextLabel") sizeLabel.Size = UDim2.new(0, 120, 0, 28) sizeLabel.Position = UDim2.new(0, 12, 0, 56) sizeLabel.BackgroundTransparency = 1 sizeLabel.Text = "Hitbox size" sizeLabel.TextColor3 = Color3.fromRGB(200, 200, 200) sizeLabel.TextSize = 14 sizeLabel.Font = Enum.Font.Gotham sizeLabel.TextXAlignment = Enum.TextXAlignment.Left sizeLabel.Parent = frame local sizeBox = Instance.new("TextBox") sizeBox.Size = UDim2.new(0, 80, 0, 28) sizeBox.Position = UDim2.new(0, 140, 0, 56) sizeBox.BackgroundColor3 = Color3.fromRGB(35, 35, 35) sizeBox.Text = tostring(currentSize) sizeBox.TextColor3 = Color3.fromRGB(255, 255, 255) sizeBox.TextSize = 14 sizeBox.Font = Enum.Font.Gotham sizeBox.ClearTextOnFocus = false sizeBox.Parent = frame Instance.new("UICorner", sizeBox).CornerRadius = UDim.new(0, 6) -- Transparency input local tLabel = Instance.new("TextLabel") tLabel.Size = UDim2.new(0, 120, 0, 28) tLabel.Position = UDim2.new(0, 12, 0, 92) tLabel.BackgroundTransparency = 1 tLabel.Text = "Transparency" tLabel.TextColor3 = Color3.fromRGB(200, 200, 200) tLabel.TextSize = 14 tLabel.Font = Enum.Font.Gotham tLabel.TextXAlignment = Enum.TextXAlignment.Left tLabel.Parent = frame local tBox = Instance.new("TextBox") tBox.Size = UDim2.new(0, 80, 0, 28) tBox.Position = UDim2.new(0, 140, 0, 92) tBox.BackgroundColor3 = Color3.fromRGB(35, 35, 35) tBox.Text = string.format("%.2f", currentTransparency) tBox.TextColor3 = Color3.fromRGB(255, 255, 255) tBox.TextSize = 14 tBox.Font = Enum.Font.Gotham tBox.ClearTextOnFocus = false tBox.Parent = frame Instance.new("UICorner", tBox).CornerRadius = UDim.new(0, 6) -- Mode toggle local modeBtn = Instance.new("TextButton") modeBtn.Size = UDim2.new(0, 120, 0, 28) modeBtn.Position = UDim2.new(0, 232, 0, 56) modeBtn.BackgroundColor3 = Color3.fromRGB(80, 80, 80) modeBtn.Text = "Mode: Proxy" modeBtn.TextColor3 = Color3.fromRGB(255, 255, 255) modeBtn.TextSize = 14 modeBtn.Font = Enum.Font.GothamBold modeBtn.Parent = frame Instance.new("UICorner", modeBtn).CornerRadius = UDim.new(0, 6) -- Toggle local toggleBtn = Instance.new("TextButton") toggleBtn.Size = UDim2.new(0, 140, 0, 36) toggleBtn.Position = UDim2.new(0, 12, 0, 136) toggleBtn.BackgroundColor3 = Color3.fromRGB(180, 35, 35) toggleBtn.Text = "Enable" toggleBtn.TextColor3 = Color3.fromRGB(255, 255, 255) toggleBtn.TextSize = 16 toggleBtn.Font = Enum.Font.GothamBold toggleBtn.Parent = frame Instance.new("UICorner", toggleBtn).CornerRadius = UDim.new(0, 8) -- Update local updateBtn = Instance.new("TextButton") updateBtn.Size = UDim2.new(0, 140, 0, 36) updateBtn.Position = UDim2.new(0, 168, 0, 136) updateBtn.BackgroundColor3 = Color3.fromRGB(40, 120, 255) updateBtn.Text = "Update" updateBtn.TextColor3 = Color3.fromRGB(255, 255, 255) updateBtn.TextSize = 16 updateBtn.Font = Enum.Font.GothamBold updateBtn.Parent = frame Instance.new("UICorner", updateBtn).CornerRadius = UDim.new(0, 8) -- Draggable do local dragging, dragStart, startPos frame.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true dragStart = input.Position startPos = frame.Position input.Changed:Connect(function() if input.UserInputState == Enum.UserInputState.End then dragging = false end end) end end) UserInputService.InputChanged:Connect(function(input) if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then local delta = input.Position - dragStart frame.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y) end end) end -- Logic local function clampSize(v) v = math.floor(v + 0.5) if v < 3 then v = 3 end if v > 60 then v = 60 end return v end local function clampTrans(v) if v < 0 then v = 0 end if v > 0.95 then v = 0.95 end return v end local function parseInputs() local s = tonumber(sizeBox.Text) local t = tonumber(tBox.Text) if s then currentSize = clampSize(s) end if t then currentTransparency = clampTrans(t) end sizeBox.Text = tostring(currentSize) tBox.Text = string.format("%.2f", currentTransparency) end local function refreshAll() if not enabled then return end -- Re-apply based on current mode removeAll() applyAll(currentSize, currentTransparency) end modeBtn.MouseButton1Click:Connect(function() mode = (mode == MODE_PROXY) and MODE_RESIZE or MODE_PROXY modeBtn.Text = "Mode: " .. mode status.Text = (mode == MODE_PROXY) and "Proxy mode • Touch & Raycast enabled" or "Resize HRP mode • Most tools will register" refreshAll() end) updateBtn.MouseButton1Click:Connect(function() parseInputs() refreshAll() end) sizeBox.FocusLost:Connect(function() parseInputs(); refreshAll() end) tBox.FocusLost:Connect(function() parseInputs(); refreshAll() end) toggleBtn.MouseButton1Click:Connect(function() parseInputs() if not enabled then setEnabled(true) toggleBtn.Text = "Disable" toggleBtn.BackgroundColor3 = Color3.fromRGB(45, 160, 75) status.Text = string.format("%s • size %d • trans %.2f", mode, currentSize, currentTransparency) else setEnabled(false) toggleBtn.Text = "Enable" toggleBtn.BackgroundColor3 = Color3.fromRGB(180, 35, 35) status.Text = "Disabled" end end) closeBtn.MouseButton1Click:Connect(function() setEnabled(false) ui:Destroy() end)