So I have an NPC that shoots at other NPCs but as the number of NPCs increases, it shoots slower than ever.
Edit: Added the videos
I am a novice scripter so If I approached this horribly you can tell me that.
The npc is shooting with a delay randomly chosen between 0.1 and 0.15 but somehow when there are more than one NPC it shoots slower.
When there is only 1 NPC, it shoots at the desired speed. I will call this NPC the “initial” NPC(Will explain further down)
When there is a bunch of NPCs but shooting at the newer duplicated NPC:
When there is a bunch of NPCs again but now shooting first at the “initial” NPC:
The code doing the work:
while true do
generateNewRandom() -- Recall a random number for firerate
wait(firerate)
local checkRay = Raycast.raycast(pointer, range) -- Check Raycasting
local target = findTarget(hrp.Position) -- Check target
local waypoints = path:GetWaypoints()
if target then
if path.Status == Enum.PathStatus.Success then
for i, v in pairs(waypoints) do
if(target.Position - hrp.Position).Magnitude < range then
if target.Parent.Humanoid.Health > 0 then
if checkRay then -- If target is in view
shoot(target) -- Look and shoot at target
else
human:MoveTo(waypoints[2].Position)
end
end
break
end
human:MoveTo(waypoints[4].Position)
end
end
end
end
The generateNewRandom() function:
local firerate -- Global variable
function generateNewRandom()
firerate = newRandom:NextNumber(.1,.15)
end
The findTarget() function:
function findTarget(pos)
local detectRange = 10000
local target
for i, v in pairs(workspace:GetChildren()) do
local model = v:IsA("Model")
if model then
local faction = v:FindFirstChild("Faction")
if faction then
if faction.Value ~= myFaction.Value then
local humanofnpc = v:FindFirstChild("Humanoid")
local hrpofnpc = v:FindFirstChild("HumanoidRootPart")
if humanofnpc and hrpofnpc and humanofnpc.Health > 0 then
if (pos - hrpofnpc.Position).Magnitude < detectRange then
target = hrpofnpc
detectRange = (pos - hrpofnpc.Position).Magnitude
path:ComputeAsync(pos, target.Position)
end
end
end
end
end
end
return target
end
The shoot() function:
function shoot(target)
local bullet = Instance.new("Part")
local bv = Instance.new("BodyVelocity")
local pointlight = Instance.new("PointLight")
pointlight.Range = 8
pointlight.Brightness = 2
pointlight.Color = Color3.new(1, 1, 0)
pointlight.Shadows = true
hrp.CFrame = CFrame.lookAt(hrp.Position, target.Position)
bullet.Anchored = false
bullet.Color = Color3.new(1, 1, 0)
bullet.Velocity = pointer.CFrame.LookVector * bulletspeed
bullet.Size = Vector3.new(.1,.1,1)
bullet.Position = pointer.Position
bullet.Material = Enum.Material.Neon
bullet.CFrame = pointer.CFrame
bv.Velocity = bullet.Velocity
bv.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
bv.P = math.huge
pointlight.Parent = bullet
bv.Parent = bullet
bullet.Parent = workspace
debris:AddItem(bullet, bulletDuration)
shootanim()
shootsound()
bullet.Touched:connect(function(hit)
local faction = hit.Parent:FindFirstChild("Faction")
local human = hit.Parent:FindFirstChild("Humanoid")
local hrp = hit.Parent:FindFirstChild("HumanoidRootPart")
local part = hit:IsA("Part")
if faction then
if human and hrp and human.Health > 0 and hit.Parent ~= npc then
human:TakeDamage(bulletdmg)
bullet:Destroy()
end
else if part and not human and not hrp and not faction and hit ~= pointer then
local dmgPart = Instance.new("Part")
dmgPart.Size = Vector3.new(.5,.5,.1)
dmgPart.Color = hit.Color
dmgPart.Material = hit.Material
dmgPart.Velocity = Vector3.new(math.random(-10,10),math.random(-10,10),math.random(-10,10))
dmgPart.Position = bullet.Position
dmgPart.CFrame = bullet.CFrame
dmgPart.Parent = workspace
bullet:Destroy()
debris:AddItem(dmgPart, 2)
end
end
end)
end
The Raycast.raycast module function:
Raycast.raycast = function(pointer, range)
local rOrigin = pointer.Position
local rDirection = pointer.CFrame.LookVector * range
local rParams = RaycastParams.new()
rParams.FilterDescendantsInstances = {pointer.Parent}
rParams.FilterType = Enum.RaycastFilterType.Blacklist
local rResult = workspace:Raycast(rOrigin, rDirection, rParams)
return rResult
end