I am controlling my NPC with only client scripts but when damaging it’s target, it would fire the damage event multiple times depending on how many players are in the game because every player would own the script.
Is there anyway to fix this?
Client AI:
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Remotes = ReplicatedStorage:WaitForChild("Remotes")
local character = script.Parent.Parent
local humanoid = character:WaitForChild("Humanoid")
local HumanoidRootPart = character:WaitForChild("HumanoidRootPart")
local Animator = humanoid:WaitForChild("Animator")
local Enemies = workspace:WaitForChild("Enemies")
local attackAnim = script:WaitForChild("AttackAnimations")
local target = nil
local seeDistance = 1000
local maxHeightDistance = 20
local damage = 4
local attackCooldown = 0.5
local attackCurrentTime = attackCooldown
local function GetNearestTarget()
local nearestDistance = seeDistance
local nearestTarget = nil
for i,v in Enemies:GetChildren() do
if v:IsA("Model") and v.PrimaryPart then
local charHumanoid = v:FindFirstChildOfClass("Humanoid")
local distanceVector = (HumanoidRootPart.Position - v.PrimaryPart.Position)
local distance = distanceVector.Magnitude
local heightDistance = math.abs(distanceVector.Y)
if charHumanoid and charHumanoid.Health > 0 and distance < nearestDistance and heightDistance <= maxHeightDistance then
nearestDistance = distance
nearestTarget = v
end
end
end
target = nearestTarget
end
local function GoToTarget()
if target and target.PrimaryPart then
humanoid:MoveTo(target.PrimaryPart.Position)
end
end
local function DamageTarget()
if target then
local targetHumanoid = target:FindFirstChildOfClass("Humanoid")
if targetHumanoid and targetHumanoid.Health > 0 then
Remotes.DamageHumanoid:FireServer(targetHumanoid, damage)
end
end
end
local function PlayAttackAnimation()
local track = Animator:LoadAnimation(attackAnim)
track:Play()
track.Stopped:Connect(function()
DamageTarget()
end)
end
local function Attack()
if target and tick() - attackCurrentTime >= attackCooldown then
attackCurrentTime = tick()
PlayAttackAnimation()
end
end
while true do
coroutine.wrap(function()
GetNearestTarget()
GoToTarget()
Attack()
end)()
task.wait(0.1)
end
Server Damage Script:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Remotes = ReplicatedStorage:WaitForChild("Remotes")
Remotes.DamageHumanoid.OnServerEvent:Connect(function(player, humanoid, damage)
if humanoid then
humanoid:TakeDamage(damage)
end
end)