Files
ClaudeCode-Roblox-Studio-MCP/examples/fps-game/part4_hud.lua
Admin a66533206f Add FPS game example, auto-connect plugin, and Python injection tools
- Updated RobloxMCPPlugin with HTTP polling (auto-enables HttpService)
- Added 20-weapon FPS game example (CoD-style)
- Added Python studio-inject.py for command bar injection via Win32 API
- Added auto-connect setup scripts (VBS + PowerShell)
- Updated MCP server with all FPS game tools

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 16:57:35 +04:00

422 lines
14 KiB
Lua

-- ═══════════════════════════════════════════════════════════════════
-- MINI CALL OF DUTY - FPS Game Setup (Part 4: HUD + Player Scripts)
-- ═══════════════════════════════════════════════════════════════════
local SG = game:GetService("StarterGui")
local SP = game:GetService("StarterPlayer")
-- ═══════════════════════════════════════════════════════════════
-- HUD (ScreenGui + LocalScript)
-- ═══════════════════════════════════════════════════════════════
local hudGui = Instance.new("ScreenGui")
hudGui.Name = "FPS_HUD"
hudGui.ResetOnSpawn = false
hudGui.IgnoreGuiInset = true
hudGui.Parent = SG
-- Crosshair
local cross = Instance.new("Frame")
cross.Name = "Crosshair"
cross.Size = UDim2.new(0, 20, 0, 20)
cross.Position = UDim2.new(0.5, -10, 0.5, -10)
cross.BackgroundTransparency = 1
cross.Parent = hudGui
for _, dir in ipairs({{0,-12,0,4,"Top"},{0,4,0,12,"Bottom"},{-12,0,4,0,"Left"},{4,0,12,0,"Right"}}) do
local line = Instance.new("Frame")
line.Name = dir[5]
line.Size = UDim2.new(0, dir[3] == 0 and 2 or dir[3], 0, dir[4] == 0 and 2 or dir[4])
line.Position = UDim2.new(0, 9+dir[1], 0, 9+dir[2])
line.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
line.BackgroundTransparency = 0.2
line.BorderSizePixel = 0
line.Parent = cross
end
-- Center dot
local dot = Instance.new("Frame")
dot.Name = "CenterDot"
dot.Size = UDim2.new(0, 3, 0, 3)
dot.Position = UDim2.new(0, 8, 0, 8)
dot.BackgroundColor3 = Color3.fromRGB(255, 50, 50)
dot.BorderSizePixel = 0
dot.Parent = cross
-- Hit marker (appears on hit)
local hitMarker = Instance.new("Frame")
hitMarker.Name = "HitMarker"
hitMarker.Size = UDim2.new(0, 30, 0, 30)
hitMarker.Position = UDim2.new(0.5, -15, 0.5, -15)
hitMarker.BackgroundTransparency = 1
hitMarker.Visible = false
hitMarker.Parent = hudGui
for _, d in ipairs({{-8,-8,6,6,45},{2,-8,6,6,-45},{-8,2,6,6,-45},{2,2,6,6,45}}) do
local mark = Instance.new("Frame")
mark.Size = UDim2.new(0, d[3], 0, d[4])
mark.Position = UDim2.new(0, 12+d[1], 0, 12+d[2])
mark.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
mark.BorderSizePixel = 0
mark.Rotation = d[5]
mark.Parent = hitMarker
end
-- Damage vignette overlay
local dmgVignette = Instance.new("Frame")
dmgVignette.Name = "DamageVignette"
dmgVignette.Size = UDim2.new(1, 0, 1, 0)
dmgVignette.BackgroundColor3 = Color3.fromRGB(200, 0, 0)
dmgVignette.BackgroundTransparency = 1
dmgVignette.BorderSizePixel = 0
dmgVignette.ZIndex = 9
dmgVignette.Parent = hudGui
-- Kill feed frame (top right)
local killFeedFrame = Instance.new("Frame")
killFeedFrame.Name = "KillFeed"
killFeedFrame.Size = UDim2.new(0, 350, 0, 150)
killFeedFrame.Position = UDim2.new(1, -360, 0, 10)
killFeedFrame.BackgroundTransparency = 1
killFeedFrame.Parent = hudGui
-- Score display (top center)
local scoreFrame = Instance.new("Frame")
scoreFrame.Name = "ScoreFrame"
scoreFrame.Size = UDim2.new(0, 200, 0, 40)
scoreFrame.Position = UDim2.new(0.5, -100, 0, 10)
scoreFrame.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
scoreFrame.BackgroundTransparency = 0.5
scoreFrame.BorderSizePixel = 0
scoreFrame.Parent = hudGui
local scoreLabel = Instance.new("TextLabel")
scoreLabel.Name = "ScoreLabel"
scoreLabel.Size = UDim2.new(1, 0, 1, 0)
scoreLabel.BackgroundTransparency = 1
scoreLabel.Text = "KILLS: 0 | DEATHS: 0"
scoreLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
scoreLabel.TextSize = 18
scoreLabel.Font = Enum.Font.GothamBold
scoreLabel.Parent = scoreFrame
-- Killstreak banner (center)
local streakBanner = Instance.new("TextLabel")
streakBanner.Name = "StreakBanner"
streakBanner.Size = UDim2.new(0, 400, 0, 60)
streakBanner.Position = UDim2.new(0.5, -200, 0.3, 0)
streakBanner.BackgroundTransparency = 1
streakBanner.Text = ""
streakBanner.TextColor3 = Color3.fromRGB(255, 200, 50)
streakBanner.TextSize = 32
streakBanner.Font = Enum.Font.GothamBold
streakBanner.TextStrokeTransparency = 0
streakBanner.Visible = false
streakBanner.ZIndex = 10
streakBanner.Parent = hudGui
-- Minimap (top left)
local minimap = Instance.new("Frame")
minimap.Name = "Minimap"
minimap.Size = UDim2.new(0, 150, 0, 150)
minimap.Position = UDim2.new(0, 10, 0, 10)
minimap.BackgroundColor3 = Color3.fromRGB(30, 40, 30)
minimap.BackgroundTransparency = 0.3
minimap.BorderSizePixel = 0
minimap.Parent = hudGui
local mapCorner = Instance.new("UICorner")
mapCorner.CornerRadius = UDim.new(0, 75)
mapCorner.Parent = minimap
local playerDot = Instance.new("Frame")
playerDot.Name = "PlayerDot"
playerDot.Size = UDim2.new(0, 6, 0, 6)
playerDot.Position = UDim2.new(0.5, -3, 0.5, -3)
playerDot.BackgroundColor3 = Color3.fromRGB(0, 255, 0)
playerDot.BorderSizePixel = 0
playerDot.Parent = minimap
-- Weapon info panel (bottom right)
local weaponPanel = Instance.new("Frame")
weaponPanel.Name = "WeaponPanel"
weaponPanel.Size = UDim2.new(0, 250, 0, 80)
weaponPanel.Position = UDim2.new(1, -260, 1, -90)
weaponPanel.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
weaponPanel.BackgroundTransparency = 0.4
weaponPanel.BorderSizePixel = 0
weaponPanel.Parent = hudGui
local weaponLabel = Instance.new("TextLabel")
weaponLabel.Name = "WeaponName"
weaponLabel.Size = UDim2.new(1, -10, 0, 25)
weaponLabel.Position = UDim2.new(0, 5, 0, 5)
weaponLabel.BackgroundTransparency = 1
weaponLabel.Text = "M4A1 CARBINE"
weaponLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
weaponLabel.TextSize = 16
weaponLabel.Font = Enum.Font.GothamBold
weaponLabel.TextXAlignment = Enum.TextXAlignment.Right
weaponLabel.Parent = weaponPanel
local ammoLabel = Instance.new("TextLabel")
ammoLabel.Name = "AmmoLabel"
ammoLabel.Size = UDim2.new(1, -10, 0, 35)
ammoLabel.Position = UDim2.new(0, 5, 0, 25)
ammoLabel.BackgroundTransparency = 1
ammoLabel.Text = "30 / 210"
ammoLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
ammoLabel.TextSize = 28
ammoLabel.Font = Enum.Font.GothamBold
ammoLabel.TextXAlignment = Enum.TextXAlignment.Right
ammoLabel.Parent = weaponPanel
local reserveLabel = Instance.new("TextLabel")
reserveLabel.Name = "ReserveLabel"
reserveLabel.Size = UDim2.new(1, -10, 0, 15)
reserveLabel.Position = UDim2.new(0, 5, 0, 60)
reserveLabel.BackgroundTransparency = 1
reserveLabel.Text = ""
reserveLabel.TextColor3 = Color3.fromRGB(180, 180, 180)
reserveLabel.TextSize = 12
reserveLabel.Font = Enum.Font.Gotham
reserveLabel.TextXAlignment = Enum.TextXAlignment.Right
reserveLabel.Parent = weaponPanel
-- Reload bar
local reloadBar = Instance.new("Frame")
reloadBar.Name = "ReloadBar"
reloadBar.Size = UDim2.new(0, 200, 0, 8)
reloadBar.Position = UDim2.new(0.5, -100, 0.6, 0)
reloadBar.BackgroundColor3 = Color3.fromRGB(40, 40, 40)
reloadBar.BorderSizePixel = 0
reloadBar.Visible = false
reloadBar.Parent = hudGui
local reloadFill = Instance.new("Frame")
reloadFill.Name = "Fill"
reloadFill.Size = UDim2.new(0, 0, 1, 0)
reloadFill.BackgroundColor3 = Color3.fromRGB(255, 200, 50)
reloadFill.BorderSizePixel = 0
reloadFill.Parent = reloadBar
-- Controls hint (bottom center)
local controlsHint = Instance.new("TextLabel")
controlsHint.Name = "Controls"
controlsHint.Size = UDim2.new(0, 600, 0, 25)
controlsHint.Position = UDim2.new(0.5, -300, 1, -30)
controlsHint.BackgroundTransparency = 1
controlsHint.Text = "WASD=Move | LMB=Shoot | RMB=ADS | Shift=Sprint | Ctrl=Crouch | R=Reload | 1-4=Weapons"
controlsHint.TextColor3 = Color3.fromRGB(150, 150, 150)
controlsHint.TextSize = 12
controlsHint.Font = Enum.Font.Gotham
controlsHint.Parent = hudGui
-- ═══════════════════════════════════════════════════════════════
-- PLAYER SETUP SCRIPT (LocalScript in StarterPlayerScripts)
-- ═══════════════════════════════════════════════════════════════
local spScripts = SP:FindFirstChild("StarterPlayerScripts")
if not spScripts then
spScripts = Instance.new("Folder")
spScripts.Name = "StarterPlayerScripts"
spScripts.Parent = SP
end
local playerSetup = Instance.new("LocalScript")
playerSetup.Name = "PlayerSetup"
playerSetup.Parent = spScripts
playerSetup.Source = [[
local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
local Events = RS:WaitForChild("Events")
local player = Players.LocalPlayer
local camera = workspace.CurrentCamera
-- Force first person
player.CameraMode = Enum.CameraMode.LockFirstPerson
player.CameraMaxZoomDistance = 0.5
player.CameraMinZoomDistance = 0.5
-- Character setup on spawn
player.CharacterAdded:Connect(function(char)
task.wait(0.5)
local hum = char:WaitForChild("Humanoid")
hum.WalkSpeed = 20
hum.JumpPower = 40
-- Health regen
task.spawn(function()
while hum and hum.Health > 0 do
task.wait(2)
if hum.Health < hum.MaxHealth and hum.Health > 0 then
hum.Health = math.min(hum.MaxHealth, hum.Health + 3)
end
end
end)
-- Damage vignette on hit
hum.HealthChanged:Connect(function(health)
local lost = hum.MaxHealth - health
if lost > 0 then
local gui = player:FindFirstChild("PlayerGui")
if gui then
local hud = gui:FindFirstChild("FPS_HUD")
if hud then
local vignette = hud:FindFirstChild("DamageVignette")
if vignette then
local intensity = math.clamp(lost / hum.MaxHealth, 0, 0.6)
vignette.BackgroundTransparency = 1 - intensity
task.delay(0.3, function()
if vignette then
vignette.BackgroundTransparency = 1
end
end)
end
end
end
end
end)
end)
-- Kill feed listener
Events:WaitForChild("KillEvent").OnClientEvent:Connect(function(data)
local gui = player:FindFirstChild("PlayerGui")
if not gui then return end
local hud = gui:FindFirstChild("FPS_HUD")
if not hud then return end
local feed = hud:FindFirstChild("KillFeed")
if not feed then return end
-- Create kill feed entry
local entry = Instance.new("TextLabel")
entry.Size = UDim2.new(1, 0, 0, 25)
entry.BackgroundTransparency = 0.4
entry.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
entry.Text = " " .. data.killer .. " [" .. data.weapon .. "] " .. data.victim
.. (data.headshot and " ★" or "")
entry.TextColor3 = data.killer == player.Name and Color3.fromRGB(50, 255, 50)
or Color3.fromRGB(255, 255, 255)
entry.TextSize = 14
entry.Font = Enum.Font.GothamBold
entry.TextXAlignment = Enum.TextXAlignment.Right
entry.BorderSizePixel = 0
-- Headshot indicator color
if data.headshot then
entry.TextColor3 = Color3.fromRGB(255, 50, 50)
end
entry.Parent = feed
-- Shift older entries down
for i, child in ipairs(feed:GetChildren()) do
if child:IsA("TextLabel") then
child.Position = UDim2.new(0, 0, 0, (i-1) * 28)
end
end
-- Remove after 5 seconds
task.delay(5, function()
if entry then entry:Destroy() end
end)
-- Killstreak banner
if data.killer == player.Name and data.streak then
local banner = hud:FindFirstChild("StreakBanner")
if banner then
local streakNames = {
[3] = "TRIPLE KILL!",
[5] = "KILLING SPREE!",
[7] = "UNSTOPPABLE!",
[10] = "TACTICAL NUKE READY!",
}
local msg = streakNames[data.streak]
if msg then
banner.Text = msg
banner.Visible = true
task.delay(3, function()
if banner then banner.Visible = false end
end)
end
end
end
end)
-- Hit marker listener
Events:WaitForChild("DamageEvent").OnClientEvent:Connect(function(data)
local gui = player:FindFirstChild("PlayerGui")
if not gui then return end
local hud = gui:FindFirstChild("FPS_HUD")
if not hud then return end
-- Show hit marker
local hm = hud:FindFirstChild("HitMarker")
if hm and data.hit then
hm.Visible = true
-- Change color for headshots
for _, child in ipairs(hm:GetChildren()) do
if child:IsA("Frame") then
child.BackgroundColor3 = data.headshot
and Color3.fromRGB(255, 50, 50)
or Color3.fromRGB(255, 255, 255)
end
end
task.delay(0.15, function()
if hm then hm.Visible = false end
end)
end
end)
-- Minimap updater
task.spawn(function()
task.wait(3)
while true do
task.wait(0.5)
local char = player.Character
if char then
local gui = player:FindFirstChild("PlayerGui")
if gui then
local hud = gui:FindFirstChild("FPS_HUD")
if hud then
local map = hud:FindFirstChild("Minimap")
if map then
-- Update enemy dots
for _, child in ipairs(map:GetChildren()) do
if child.Name == "EnemyDot" then child:Destroy() end
end
for _, obj in ipairs(workspace:GetChildren()) do
if obj.Name:match("^Enemy_") then
local hum = obj:FindFirstChildOfClass("Humanoid")
if hum and hum.Health > 0 then
local root = obj:FindFirstChild("HumanoidRootPart")
if root and char:FindFirstChild("Head") then
local relPos = root.Position - char.Head.Position
local mapScale = 150 / 400 -- minimap size / map size
local mx = math.clamp(relPos.X * mapScale + 72, 5, 145)
local mz = math.clamp(relPos.Z * mapScale + 72, 5, 145)
local eDot = Instance.new("Frame")
eDot.Name = "EnemyDot"
eDot.Size = UDim2.new(0, 5, 0, 5)
eDot.Position = UDim2.new(0, mx, 0, mz)
eDot.BackgroundColor3 = Color3.fromRGB(255, 50, 50)
eDot.BorderSizePixel = 0
eDot.Parent = map
end
end
end
end
end
end
end
end
end
end)
print("[PlayerSetup] FPS player configured.)
]]
print("[CoD FPS] Part 4/5 complete: HUD + Player scripts created.")