Need help with AI not working when replicated

The ally NPC’s AI doesn’t work when it’s cloned from ReplicatedStorage into workspace.
I want this issue to be fixed, I tried cloning it from ServerStorage instead but that didn’t work either.

How it works is that I press a GUI button to summon the NPC from a portal, however the enemy just stands there motionless when it spawned. How can I fix this?

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local UIS = game:GetService("UserInputService")
local Cubes = ReplicatedStorage:WaitForChild("Cubes")
local Events = ReplicatedStorage:WaitForChild("Events")
local spawncubeEvent = Events:WaitForChild("SpawnCube")

local cubeToSpawn = nil

local function SpawnCube(cube,portal)
	local cubeExists = Cubes:FindFirstChild(cube)
	if cubeExists then
		cubeToSpawn = cubeExists:Clone()
		cubeToSpawn.Parent = workspace.Cubes
		cubeToSpawn:SetPrimaryPartCFrame(portal.Spawner.CFrame)
		cubeToSpawn.PrimaryPart.Anchored = false
		
		local BodyGyro = Instance.new("BodyGyro")
		BodyGyro.MaxTorque = Vector3.new(math.huge,math.huge,math.huge)
		BodyGyro.D = 0
		BodyGyro.CFrame = cubeToSpawn.HumanoidRootPart.CFrame
		BodyGyro.Parent = cubeToSpawn.HumanoidRootPart
		for i, object in ipairs(cubeToSpawn:GetDescendants()) do
			if object:IsA("BasePart") then
				object.CollisionGroup = "Allies"
			end
		end

	end
end


script.Parent.Activated:Connect(function()
	SpawnCube("Cube",workspace.Portal)
end)

Cubes are the NPCs mentioned.

1 Like

What scripts has the “AI” ? I mean the “Cube” rig has? what scripts it has to have movement, animations, behaviour?

That script (client or server sided) will clone a rig, place it in workspace, apply a BodyGyro bodymover (to set the orientation to the original one the “cube” has) and change its collision group to “Allies”
And thats all, it wont have any movement, animation or behaviour cause theres no scripts for that. Its only a rig in workspace with collisions to “Allies”

The Cube has a script inside it’s Humanoid that runs it’s behavior. It seems like it doesn’t run when it’s cloned into workspace and I’m no sure why…

Send the script that is inside that rig, its server or client? Paste it in here

It’s a server script.

local Enemies = workspace.Enemies
local Humanoid = script.Parent
local Self = Humanoid.Parent
local AttackEffect = Self.HumanoidRootPart.ParticleEmitter
local AttackAnim = Self.Attack
local DeathAnim = Self.Defeat
local Animation = Humanoid:LoadAnimation(AttackAnim)
local Defeat = Humanoid:LoadAnimation(DeathAnim)
local RunService = game:GetService("RunService")
local LastAttack = tick()

--Stats--
local Damage = script:GetAttribute("Damage")
local AttackRange = script:GetAttribute("AttackRange")
local Cooldown = script:GetAttribute("Cooldown")
local Range = script:GetAttribute("Range")


local target = nil

local function FindNearestTarget()
	local EnemyList = Enemies:GetChildren()
	
	local nearesttarget = nil
	local distance = nil
	local direction = nil
	for _, target in pairs(EnemyList) do
		if target then
			local distanceVector = (target.PrimaryPart.Position - Self.PrimaryPart.Position)
			if not nearesttarget then
				nearesttarget = target
				distance = distanceVector.Magnitude
				direction = distanceVector.Unit
			elseif distanceVector.Magnitude < distance then
				nearesttarget = target
				distance = distanceVector.Magnitude
				direction = distanceVector.Unit
			end
		end
	end
	--print(nearesttarget)
	return nearesttarget,distance,direction
end

RunService.Stepped:Connect(function()
	local nearesttarget,distance,direction = FindNearestTarget()
	if nearesttarget and nearesttarget:FindFirstChildOfClass("Humanoid") ~= nil then
		if distance <= Range and distance >= AttackRange then
			Humanoid:Move(direction)
		else
			Humanoid:Move(Vector3.new())
		end
		
		if distance <= AttackRange and tick() - LastAttack >= Cooldown then
			local EnemyHumanoid = nearesttarget:FindFirstChildOfClass("Humanoid")
			LastAttack = tick()
			EnemyHumanoid:TakeDamage(Damage)
			Animation:Play()
		end
	end
end)

Humanoid.Died:Connect(function()
	Defeat:Play()
	Defeat.Ended:Wait()
	Self:Destroy()
end)

1 Like

You should do this on server side. Use a remoteEvent from client, and server should perform the cloning from ServerStorage and place the “Cube” in workspace.Cubes. Thats why the server script inside Cube its not running, cause you are clonning it and parenting it from client side.

Do the test with these scripts:

A local script inside a button, button is parented to a SurfaceGui in StarterGui.
I added a folder called “Remotes” inside ReplicatedStorage and a RemoteEvent in there called “SpawnNPC_BTN”

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UIS = game:GetService("UserInputService")

-- Theres a folder called Remotes inside ReplicatedStorage, with a RemoteEvent called SpawnNPC_BTN
local SpawnNPC_BTN = ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("SpawnNPC_BTN")

script.Parent.Activated:Connect(function()
	SpawnNPC_BTN:FireServer("Cube", workspace.Portal)
end)

A ServerScript listening to the RemoteEvent fired by the client:
I placed the Cube NPC into a folder called Cubes in ServerStorage

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local SpawnNPC_BTN = ReplicatedStorage:WaitForChild("Cubes"):WaitForChild("Remotes"):WaitForChild("SpawnNPC_BTN")

-- Cube is in ServerStorage in a folder called Cubes
local Cubes = game.ServerStorage:WaitForChild("Cubes")

SpawnNPC_BTN.OnServerEvent:Connect(function(player, cube, portal)
	--warn(player, cube, portal)
	local cubeExists = Cubes:FindFirstChild(cube)
	if cubeExists then
		local cubeToSpawn = cubeExists:Clone()
		cubeToSpawn.Parent = workspace.Cubes
		cubeToSpawn:SetPrimaryPartCFrame(portal.Spawner.CFrame)
		cubeToSpawn.PrimaryPart.Anchored = false

		local BodyGyro = Instance.new("BodyGyro")
		BodyGyro.MaxTorque = Vector3.new(math.huge,math.huge,math.huge)
		BodyGyro.D = 0
		BodyGyro.CFrame = cubeToSpawn.HumanoidRootPart.CFrame
		BodyGyro.Parent = cubeToSpawn.HumanoidRootPart
		for i, object in ipairs(cubeToSpawn:GetDescendants()) do
			if object:IsA("BasePart") then
				object.CollisionGroup = "Allies"
			end
		end
	end
end)

A ServerScript inside the NPC “Cube”, its placed inside HumanoidRootPart:
This is for testing. Do not use your AI script, use this one, and check output, if you see the prints and warns then the server script is running normally, after that you can replace this script with the AI one:

print("Im a cube with a script running")
while true do
	warn("yeah im a cube")
	task.wait(1)
end

Or do the test with this file, it contains your scripts and stuff edited so you can see RemoteEvent works well and “AI” script runs, just check output
SpawnPortal.rbxl (54.7 KB)

1 Like

Thank you, the cube is acting normally as planned. :smiley:

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.