Hello, I have some problems with my NPCs, I making game where 2 teams (red and blue) war with each other, looks like everything is working but not really. So I can’t really say why it’s happeing but they starting to behave kind weird, they starting to fall, sometimes do nothing, and they don’t have default animations (I using Animate script for it and also I have my own animations like Attack, Spawn, and etc. I using for that client, fire all clients from server to client). When I rechecked some times the code and experimented, then when I added task.wait() in some certain places, everything seemed to start working, but if I played a little longer, the default animations disapper and the NPCs began to fall when shooting or when spawning. I’ve already looked through the devforum and I haven’t found a similar problem anywhere, I have no idea why this is happening (although maybe my code is just bad). So I could really use some help.
This is my code:
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local mechanics = require(script.Mechanics)
local guns = ServerStorage:WaitForChild("Guns")
local events = ReplicatedStorage:WaitForChild("Events")
local playAnimationEvent = events:WaitForChild("PlayAnimation")
local tween_on_death = TweenInfo.new(3, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut, 0, false, 0)
local tween_on_spawn = TweenInfo.new(1, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut, 0, false, 0)
local teams_folder = workspace:WaitForChild("Teams")
local red_team = teams_folder.Red
local blue_team = teams_folder.Blue
local teams = {}
function teams.Random_NPC()
local possible_NPCs = ReplicatedStorage.NPCs:GetChildren()
local random_NPC = possible_NPCs[math.random(1, #possible_NPCs)]
return random_NPC
end
function teams.Random_Gun(new_NPC)
local possible_guns = guns:GetChildren()
local randomGun = possible_guns[math.random(1, #possible_guns)]
local new_gun = randomGun:Clone()
new_NPC.Humanoid:EquipTool(new_gun)
end
function teams.Random_Spawn(spawns)
local random = math.random(1, #spawns:GetChildren())
local random_spawn = spawns[random]
return random_spawn
end
function teams.Optimize(new_NPC)
local humanoid = new_NPC:FindFirstChild("Humanoid")
if new_NPC:FindFirstChild("HumanoidRootPart") then
new_NPC.HumanoidRootPart:SetNetworkOwner(nil)
elseif new_NPC.PrimaryPart ~= nil then
new_NPC.PrimaryPart:SetNetworkOwner(nil)
end
if not humanoid then return end
humanoid:SetStateEnabled(Enum.HumanoidStateType.Seated, false)
humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, false)
humanoid:SetStateEnabled(Enum.HumanoidStateType.Running, false)
humanoid:SetStateEnabled(Enum.HumanoidStateType.GettingUp, false)
humanoid:SetStateEnabled(Enum.HumanoidStateType.Climbing, false)
humanoid:SetStateEnabled(Enum.HumanoidStateType.Landed, false)
humanoid:SetStateEnabled(Enum.HumanoidStateType.Ragdoll, false)
humanoid:SetStateEnabled(Enum.HumanoidStateType.Freefall, false)
end
local function Get_Team_Target(new_NPC)
if new_NPC.Parent.Name == "Red" then
return "Blue"
elseif new_NPC.Parent.Name == "Blue" then
return "Red"
else
warn("No team")
end
end
local function Find_Nearest_Target(new_NPC)
local max_distance = 1000
local team_target = Get_Team_Target(new_NPC)
local nearest_target = nil
for i, target in pairs(workspace.Teams[team_target]:GetChildren()) do
if target:FindFirstChild("HumanoidRootPart") and target:FindFirstChild("Humanoid") and target.Humanoid.Health > 0 and new_NPC:FindFirstChild("HumanoidRootPart") then
local distance = (new_NPC.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude
if distance < max_distance then
nearest_target = target
max_distance = distance
end
end
end
return nearest_target
end
function teams.AI(new_NPC)
local tool = new_NPC:FindFirstChildOfClass("Tool")
local target = Find_Nearest_Target(new_NPC)
if target and target:FindFirstChild("Humanoid") and target.Humanoid.Health > 0 and new_NPC and new_NPC:FindFirstChild("Humanoid") and new_NPC.Humanoid.Health > 0 and tool then
local distance = (new_NPC.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude
if distance < tool:GetAttribute("Range") then
new_NPC.Humanoid:MoveTo(new_NPC.HumanoidRootPart.Position)
new_NPC.HumanoidRootPart.CFrame = CFrame.new(new_NPC.HumanoidRootPart.Position, Vector3.new(target.Torso.Position.X, new_NPC.HumanoidRootPart.Position.Y, target.Torso.Position.Z))
playAnimationEvent:FireAllClients(new_NPC, "Attack")
if tool:GetAttribute("Is_Explosion") then
mechanics.SplashDamage(target, new_NPC)
else
if not target:FindFirstChild("ShieldThing") then
target.Humanoid.Health -= tool:GetAttribute("Damage")
end
end
task.wait(tool:GetAttribute("Cooldown"))
else
new_NPC.Humanoid:MoveTo(target.HumanoidRootPart.Position)
end
else
new_NPC.Humanoid:MoveTo(new_NPC.HumanoidRootPart.Position)
end
task.wait()
if new_NPC and new_NPC.Parent then
coroutine.wrap(teams.AI)(new_NPC)
end
end
function teams.On_Spawn(new_NPC)
local humanoid_root_part = new_NPC:WaitForChild("HumanoidRootPart", 3)
if humanoid_root_part then
humanoid_root_part.Anchored = true
local forcefield = Instance.new("ForceField")
forcefield.Name = "ShieldThing"
forcefield.Parent = new_NPC
for _, part in ipairs(new_NPC:GetDescendants()) do
if part:IsA("BasePart") and part.Name ~= "HumanoidRootPart" and part.Name ~= "FirePart" or part:IsA("Decal") then
part.Transparency = 1
TweenService:Create(part, tween_on_spawn, {Transparency = 0}):Play()
end
end
playAnimationEvent:FireAllClients(new_NPC, "OnSpawn")
task.wait(1.15)
humanoid_root_part.Anchored = false
coroutine.wrap(teams.AI)(new_NPC)
task.wait(0.85)
forcefield:Destroy()
end
end
function teams.Spawn_Red(spawns)
local random_spawn = teams.Random_Spawn(spawns)
local random_NPC = teams.Random_NPC()
local new_NPC = random_NPC:Clone()
new_NPC:PivotTo(random_spawn.CFrame - Vector3.new(0, (new_NPC.HumanoidRootPart.Size.Y / 2) + (new_NPC:FindFirstChild("Left Leg").Size.Y / 2), 0))
new_NPC.Parent = workspace.Teams.Red
teams.Optimize(new_NPC)
teams.Random_Gun(new_NPC)
new_NPC.Humanoid.Died:Connect(function()
for i, joint in pairs(new_NPC:GetDescendants()) do
if joint:IsA("Motor6D") and joint.Name == "Right Hip" or joint.Name == "Left Hip" or joint.Name == "Neck" or joint.Name == "Left Shoulder" or joint.Name == "Right Shoulder" or joint.Name == "Root" then
local socket = Instance.new("BallSocketConstraint")
local a1 = Instance.new("Attachment")
local a2 = Instance.new("Attachment")
a1.Parent = joint.Part0
a2.Parent = joint.Part1
socket.Parent = joint.Parent
socket.Attachment0 = a1
socket.Attachment1 = a2
a1.CFrame = joint.C0
a2.CFrame = joint.C1
socket.LimitsEnabled = true
socket.TwistLimitsEnabled = true
joint:Destroy()
end
end
task.wait(17)
for i, part in pairs(new_NPC:GetDescendants()) do
if part:IsA("BasePart") and part.Name ~= "HumanoidRootPart" and part.Name ~= "FirePart" or part:IsA("Decal") then
TweenService:Create(part, tween_on_death, {Transparency = 1}):Play()
end
end
task.wait(3)
new_NPC:Destroy()
end)
task.wait()
coroutine.wrap(teams.On_Spawn)(new_NPC)
end
function teams.Spawn_Blue(spawns)
local random_spawn = teams.Random_Spawn(spawns)
local random_NPC = teams.Random_NPC()
local new_NPC = random_NPC:Clone()
new_NPC:PivotTo(random_spawn.CFrame - Vector3.new(0, (new_NPC.HumanoidRootPart.Size.Y / 2) + (new_NPC:FindFirstChild("Left Leg").Size.Y / 2), 0))
new_NPC.Parent = workspace.Teams.Blue
teams.Optimize(new_NPC)
teams.Random_Gun(new_NPC)
new_NPC.Humanoid.Died:Connect(function()
for i, joint in pairs(new_NPC:GetDescendants()) do
if joint:IsA("Motor6D") and joint.Name == "Right Hip" or joint.Name == "Left Hip" or joint.Name == "Neck" or joint.Name == "Left Shoulder" or joint.Name == "Right Shoulder" or joint.Name == "Root" then
local socket = Instance.new("BallSocketConstraint")
local a1 = Instance.new("Attachment")
local a2 = Instance.new("Attachment")
a1.Parent = joint.Part0
a2.Parent = joint.Part1
socket.Parent = joint.Parent
socket.Attachment0 = a1
socket.Attachment1 = a2
a1.CFrame = joint.C0
a2.CFrame = joint.C1
socket.LimitsEnabled = true
socket.TwistLimitsEnabled = true
joint:Destroy()
end
end
task.wait(17)
for i, part in pairs(new_NPC:GetDescendants()) do
if part:IsA("BasePart") and part.Name ~= "HumanoidRootPart" and part.Name ~= "FirePart" or part:IsA("Decal") then
TweenService:Create(part, tween_on_death, {Transparency = 1}):Play()
end
end
task.wait(3)
new_NPC:Destroy()
end)
task.wait()
coroutine.wrap(teams.On_Spawn)(new_NPC)
end
return teams