Im trying to make a stealth game, im trying to make the detection meter gui position in the direction of the enemy, but it only works for one enemy. The rest just show up as regular ui on your screen.
https://gyazo.com/31d6fa50929e5ad3c956f6cd488dd1c8
I cannot provide my class module script as its too long so here is the tutorial i followed: https://devforum.roblox.com/t/how-to-make-a-stealth-system/926417
Stealth Controller:
-- Controller local StealthController = {} -- Roblox Services local RunService = game:GetService("RunService") -- Modules local Enemy -- Table to store our enemies local enemies = {} -- The folder with the models of our enemies local enemyFolder = workspace:WaitForChild("enemies"):GetChildren() local plr: Player? = (RunService:IsClient()) and game:GetService("Players").LocalPlayer local Markers = {} local Screen = plr:WaitForChild("PlayerGui"):WaitForChild("DetectionUIS"):WaitForChild("Holder").AbsoluteSize local ReplicatedStorage = game:GetService("ReplicatedStorage") local T = game:GetService("TweenService") -- Types -- this is poggers men! type Enemy = { -- Properties enemy: Model, OnDetected: RBXScriptSignal, detected: boolean, detecting: boolean, distance: number, detectionMeter: number, player: Player?, combatSettings: { damage: number, attackCooldown: number, range: number }, animations: { fire: AnimationTrack, reload: AnimationTrack, walk: AnimationTrack }, detectionSettings: { FOV: number, maxDistance: number, minDetection: number, maxDetection: number, DISTANCE_CONSTANT: number }, -- Objects detectionBar: Frame?, -- Methods new: (Model) -> Enemy, DoChecks: () -> nil, MoveToNextPoint: () -> nil, -- Private methods _behindObstacle: () -> boolean, _withinFOV: () -> boolean, _withinDistance: () -> boolean, _updateGUI: () -> nil, Init: () -> nil } -- Controller initialization function StealthController:Init() -- Assign enemy Enemy = self.Shared.Enemy end function ClampMarkerToBorder(X,Y,Absolute) X = Screen.X - X Y = Screen.Y - Y local DistanceToXBorder = math.min(X,Screen.X-X) local DistanceToYBorder = math.min(Y,Screen.Y-Y) if DistanceToYBorder < DistanceToXBorder then if Y < (Screen.Y-Y) then return math.clamp(X,0,Screen.X-Absolute.X),0 else return math.clamp(X,0,Screen.X-Absolute.X),Screen.Y - Absolute.Y end else if X < (Screen.X-X) then return 0,math.clamp(Y,0,Screen.Y-Absolute.Y) else return Screen.X - Absolute.X,math.clamp(Y,0,Screen.Y-Absolute.Y) end end end function StealthController:Start() -- Loop through the enemies's models for enemyIndex: number, enemy: Model in ipairs(enemyFolder) do -- Create an instance of the Enemy class local newEnemy = Enemy.new(enemy) -- Create a key for our new Enemy object enemies[enemy.Name .. enemyIndex] = newEnemy local Marker = plr:WaitForChild("PlayerGui").DetectionUIS.detectionBar Marker.Parent = plr:WaitForChild("PlayerGui"):WaitForChild("DetectionUIS").Holder game:GetService("RunService").Heartbeat:Connect(function() --if plr.PlayerGui:WaitForChild("DetectedUI").Enabled == true then return end local Location = enemy.Head --Marker.Visible = Location.Config.Enabled.Value local MarkerPosition = game.Workspace.CurrentCamera:WorldToScreenPoint(Location.Position) local MarkerRotation = game.Workspace.CurrentCamera.CFrame:Inverse()*Location.CFrame local MarkerAbsolute = plr:WaitForChild("PlayerGui"):WaitForChild("DetectionUIS").Holder:FindFirstChild("detectionBar").AbsoluteSize local MarkerPositionX = MarkerPosition.X - MarkerAbsolute.X/2 local MarkerPositionY = MarkerPosition.Y - MarkerAbsolute.Y/2 if MarkerPosition.Z < 0 then MarkerPositionX,MarkerPositionY = ClampMarkerToBorder(MarkerPositionX,MarkerPositionY,MarkerAbsolute) else if MarkerPositionX < 0 then MarkerPositionX = 0 elseif MarkerPositionX > (Screen.X - MarkerAbsolute.X) then MarkerPositionX = Screen.X - MarkerAbsolute.X end if MarkerPositionY < 0 then MarkerPositionY = 0 elseif MarkerPositionY > (Screen.Y - MarkerAbsolute.Y) then MarkerPositionY = Screen.Y - MarkerAbsolute.Y end plr:WaitForChild("PlayerGui"):WaitForChild("DetectionUIS").Holder:FindFirstChild("detectionBar").RotateLabel.Rotation = 90 + math.deg(math.atan2(MarkerRotation.Z,MarkerRotation.X)) plr:WaitForChild("PlayerGui"):WaitForChild("DetectionUIS").Holder:FindFirstChild("detectionBar").Position = UDim2.new(0,MarkerPositionX,0,MarkerPositionY) --T:Create(Marker,TweenInfo.new(.5),{ImageColor3 = Location.Config.MarkerColor.Value}):Play() --T:Create(Marker.RotateLabel.Arrow,TweenInfo.new(.5),{ImageColor3 = Location.Config.MarkerColor.Value}):Play() end end) -- Connect the .OnDetected event local onDetected: RBXScriptConnection onDetected = newEnemy.OnDetected:Connect(function() print("Detected!") plr:WaitForChild("PlayerGui") local detectedui = plr.PlayerGui:WaitForChild("DetectedUI") detectedui.Enabled = true detectedui.TextLabel.Text = (plr.Name.. " was seen!") onDetected:Disconnect() return end) end -- Function to be run every heartbeat local function heartBeat(_: number) -- Loops through our enemies for _: string, enemy: Enemy in pairs(enemies) do -- If enemy has been detected, skip the iteration to not call the method if (enemy.detected) then continue end enemy:DoChecks() end end RunService.Heartbeat:Connect(heartBeat) end return StealthController