local Turret = script.Parent.Turret
while task.wait(0.035) do
local Player = Players:GetPlayers()
local playerTable = {}
for Index, Value in pairs(Player) do
pcall(function()
if Value.Character:FindFirstChild("Humanoid") and Value.Character.Humanoid.Health > 0 then
table.insert(playerTable, #playerTable+1, Value.Character)
end
end)
end
local VisionDistance = 150
local Target
for _, Value in pairs(playerTable) do
local Humrp = Value.HumanoidRootPart
local Distance = (Humrp.Position-Turret.Cube.Position).Magnitude
local RayParams = RaycastParams.new()
RayParams.FilterType = Enum.RaycastFilterType.Exclude
RayParams.FilterDescendantsInstances = Turret.Parent:GetDescendants()
local CanSee = workspace:Raycast(Turret.Cube.Position, (Humrp.Position-Turret.Cube.Position).Unit*VisionDistance, RayParams)
if Distance < VisionDistance and CanSee and CanSee.Instance:IsDescendantOf(Value) then
Target = Humrp
VisionDistance = Distance
end
end
if Target then
print("target found")
Turret.Cube.CFrame = CFrame.new(Turret.Cube.Position, Target.Position)
elseif not Target then
print("no target")
end
end
This code is fully functional, but it lags my game, I can only imagine how bad it would be if multiple players spawned in a turret like this… So what I want to do is optimize the code so it doesn’t lag my game. I was thinking instead of using a while true loop, maybe do Players.PlayedAdded for the player table, and a run service when it finds a player to rotate the turret towards the player, I don’t really know how to do that, does anyone mind helping me out?
There may be more but here’s a list of things you could fix/modify
Use one of the RunService events as opposed to an infinite wait loop (probably Heartbeat)
Separate the player target table from the loop
Realistically, you don’t need to update the list every every frame, just whenever a character is modified/a change to the list would need to be made. (ex: A player dies, a new character is added)
In addition to that last note, remove the GetPlayers from the main loop
Move the RayParams establishment outside of the loop. (and FilterType =)
You don’t need to make a new RayParams every frame, just to update the FilterDescendantsInstances value of it
Although it’s slightly more work than the other optimization methods and won’t provide as much as a payoff…
…You could disable CanQuery on all of the accessory BaseParts on all the characters, subsequentially exempting them from the raycast, and swap out IsDecendantOf(Value) to a Parent == Value comparison
tldr; use more events and move non-changing variables outside of the loop
Removing the :GetPlayers() from the loop, how would i add another player to the table when a new one joins… I know there’s Players.PlayerAdded() but I wouldn’t know how to implement that.
-- services
local Players = game:GetService("Players") -- Just getting the service
-- variables
local targetList = {} -- List of all the characters to be targetted
-- logic
Players.PlayerAdded:Connect(function(addedPlr)
addedPlr.CharacterAdded:Connect(function(addedChar)
targetList[addedPlr] = addedChar -- Uses the addedPlr as the index for the character, so it can be easily removed later
end)
end)
Players.PlayerRemoving:Connect(function(removingPlr)
targetList[removingPlr] = nil -- Removes any previously stored character of the leaving player
end)
You can also use events like CharacterRemoving, Humanoid.Died, or Instance.Destroying on the character to determine if the character/character root needs to be removed from the target list.
I recommend looking into learning events if you’ve yet to, they’ll change your life.
edit: if the code’s local then you’d want to connect the added event & then sort through all the already existing players, incase a player joins later
CharacterAdded gets fired whenever a character respawns as well, or should at least. I believe calling Player:LoadCharacter() may not fire CharacterAdded but I’m unsure off the top of my head
You’re saying that CharacterAdded gets fired whenever a character respawns as well, but in the script character added is only being called when a player is added, so if a player is added and it dies, when it respawns the characteradded event wont fire.
The CharacterAdded event is an event attached to the Player, not the Players service
" The CharacterAdded event fires when a player’s character spawns (or respawns). This event fires soon after setting Player.Character to a non-nil value or calling Player:LoadCharacter(), which is before the character is parented to the Workspace."