Need help on Script

So I’m doing a script that handles with the Enemy on my game, it’s a RPG one. I’ve made a script that handles with each enemy on the game, it contains parts that handles Properties, Follow, Damage, Award and stuff. Althought, I am witnessing a problem with the Follow function, Respawn, Award function. I don’t know what is happening and I need help to improve my script so everything is fine.

**The Script: **

local players = game:GetService("Players")
local mobs = workspace:WaitForChild("Mobs")

local function Damage(hit, _M)
	if (not players:GetPlayerFromCharacter(hit.Parent)) then return end
	local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
	if (not plr.Character) then return end
	local chr = plr.Character
	if (not chr:FindFirstChild("Humanoid")) then return end
	local hum = chr.Humanoid
	if chr:FindFirstChild("ForceField") then return end
	hum.Health = hum.Health - _M.MobDamage
end

function FindTarget(_M, Enemy)
	local maxDistance = _M.FollowDistance
	local mob = Enemy.Parent
	for _, v in pairs(game.Players:GetPlayers()) do
		if v.Character and v.Character:FindFirstChild("Humanoid") then
			local torso = v.Character:FindFirstChild("Torso")
			if torso and (torso.Position - mob.Torso.Position).magnitude <= maxDistance then
				local target = torso
				task.wait(0.1)
				return target
			end
		end
	end
end

local function Respawn(_M, Mob)
	local MobClone = Mob:Clone()
	task.wait(_M.RespawnTime)
	Mob:Destroy()
	MobClone.Parent = mobs
	MobClone:MakeJoints()
end

local function Award(Mob, Enemy, _M)
	if (Mob == nil) or (Enemy == nil) then return end
	if (not Enemy:FindFirstChild("Player_Tag")) then return end
	local Tag = Enemy:FindFirstChild("Player_Tag")
	if (not Tag) and (not Tag.Value) then return end
	local plr = Tag.Value :: Player
	if (not plr:FindFirstChild("leaderstats")) then return end
	local stats = plr:FindFirstChild("leaderstats")
	if (not plr:FindFirstChild("EXP")) then return end
	if (not plr:FindFirstChild("Gold")) then return end
	task.wait(0.1)
	if stats.LOVE.Value < _M.LevelRequiredToKill then return end
	plr.EXP.Value += _M.AwardedXP
	plr.Gold.Value += _M.AwardedGold
end

local function TeleportOnKill(_M, Enemy)
	if (not _M.DoesMobTeleportAfterKill) then return end
	local tag = Enemy:FindFirstChild("Player_Tag")
	if (tag==nil) or (tag.Value==nil) then return end
	print(tag)
	local chr = tag.Value.Character or tag.Value.CharacterAdded:Wait()
	local root = chr:FindFirstChild("HumanoidRootPart")
	if (chr==nil) and (root==nil) then return end
	root.CFrame = _M.TeleportLocation + Vector3.new(0,3,0)
end

local Attributes = function(Enemy, module)
	local UI = Enemy.BillboardGui
	local textlabel = UI:WaitForChild("TextLabel")

	local MName = module.MobName :: string
	local MRank = module.RankName :: string

	Enemy.MaxHealth = module.MobHealth
	Enemy.Health = Enemy.MaxHealth
	Enemy.WalkSpeed = module.MobWalkSpeed
	textlabel.Text = MName.."["..MRank.."]"
end

local DealDamage = function(Enemy,module, mob)
	local debounce = false

	mob.Torso.Touched:Connect(function(hit)
		if (Enemy.Health < 1) then return end
		if debounce then return end
		debounce = true
		Damage(hit, module)
		task.wait(.7)
		debounce = false
	end)
end
  
local OnDied = function(Enemy, module, mob)
	Enemy.Died:Connect(function()
		coroutine.wrap(Respawn)(module, mob)
		coroutine.wrap(Award)(mob, Enemy, module)
		TeleportOnKill(module,Enemy)
	end)
end

local Follow = function(Enemy, _M)
	while _M.FollowDelay do
		local target = FindTarget(_M, Enemy)
		print(target)
		if target then
			Enemy.Humanoid:MoveTo(target.Position)
		end
	end
end

local function LoadCharacter(Enemy, _M, instance)
	Attributes(Enemy, _M)
	Follow(Enemy,_M)
end

for _,v in pairs(game:GetService("CollectionService"):GetTagged("Mobs")) do
	if (not v:IsA("Model")) then return end
	if (not require(v.MobConfig)) then return end
	if not v:FindFirstChild("Enemy") then return end
	local Enemy = v.Enemy :: Humanoid
	local _M = require(v.MobConfig)
	LoadCharacter(Enemy,_M,v)
	OnDied(Enemy, _M, v)
	coroutine.wrap(DealDamage)(Enemy, _M, v)
end

mobs.ChildAdded:Connect(function(c)
	if not c:IsA("Model") then return end
	if not c:FindFirstChild("Enemy") then return end
	local Enemy = c:FindFirstChild("Enemy")
	local _M = require(c.MobConfig)
	LoadCharacter(Enemy, _M, c)
	OnDied(Enemy, _M, c)
	coroutine.wrap(DealDamage)(Enemy, _M, c)
end)

Thank you in advance.

3 Likes

I am confused. Please elaborate, show errors if there are any, or describe the issue compared to your goal.

Ok sorry, So I am doing a script that make enemies on my game follow the player, damage the player, change its life, walkspeed, respawn when died… Well you can see that there, but I am witnessing problems with follow which the target returns nil, in other words, it is not findind the player’s torso even when he is right on the position that the enemy can follow.

Respawn function is also not working, the enemy is not respawning, and it shows no problem, no errors. And even if the enemy respawn, it would have all the properties the old enemy had.

Award script is also not showing errors but is not giving player EXP nor GOLD.

local players = game:GetService("Players")
local mobs = workspace:WaitForChild("Mobs")

local function Damage(hit, _M)
	if (not players:GetPlayerFromCharacter(hit.Parent)) then return end
	local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
	if (not plr.Character) then return end
	local chr = plr.Character
	if (not chr:FindFirstChild("Humanoid")) then return end
	local hum = chr.Humanoid
	if chr:FindFirstChild("ForceField") then return end
	hum.Health = hum.Health - _M.MobDamage
end

function FindTarget(_M, Enemy)
	local maxDistance = _M.FollowDistance
	local mob = Enemy.Parent
	for _, v in pairs(game.Players:GetPlayers()) do
		if v.Character and v.Character:FindFirstChild("Humanoid") then
			local torso = v.Character:FindFirstChild("Torso")
			if torso and (torso.Position - mob.Torso.Position).magnitude <= maxDistance then
				local target = torso
				task.wait(0.1)
				return target
			end
		end
	end
end

local function Respawn(_M, Mob,loadcharacter) -- Not respawning(no errors on output)
	local MobClone = Mob:Clone()
	task.wait(_M.RespawnTime)
	Mob:Destroy()
	MobClone.Parent = mobs
	MobClone:MakeJoints()
end

local function Award(Mob, Enemy, _M) -- Not giving player's award(no errors on output)
	if (Mob == nil) or (Enemy == nil) then return end
	if (not Enemy:FindFirstChild("Player_Tag")) then return end
	local Tag = Enemy:FindFirstChild("Player_Tag")
	if (not Tag) and (not Tag.Value) then return end
	local plr = Tag.Value :: Player
	if (not plr:FindFirstChild("leaderstats")) then return end
	local stats = plr:FindFirstChild("leaderstats")
	if (not plr:FindFirstChild("EXP")) then return end
	if (not plr:FindFirstChild("Gold")) then return end
	task.wait(0.1)
	if stats.LOVE.Value < _M.LevelRequiredToKill then return end
	plr.EXP.Value += _M.AwardedXP
	plr.Gold.Value += _M.AwardedGold
end

local function TeleportOnKill(_M, Enemy)
	if (not _M.DoesMobTeleportAfterKill) then return end
	local tag = Enemy:FindFirstChild("Player_Tag")
	if (tag==nil) or (tag.Value==nil) then return end
	print(tag)
	local chr = tag.Value.Character or tag.Value.CharacterAdded:Wait()
	local root = chr:FindFirstChild("HumanoidRootPart")
	if (chr==nil) and (root==nil) then return end
	root.CFrame = _M.TeleportLocation + Vector3.new(0,3,0)
end

local Attributes = function(Enemy, module)
	local UI = Enemy.BillboardGui
	local textlabel = UI:WaitForChild("TextLabel")

	local MName = module.MobName :: string
	local MRank = module.RankName :: string

	Enemy.MaxHealth = module.MobHealth
	Enemy.Health = Enemy.MaxHealth
	Enemy.WalkSpeed = module.MobWalkSpeed
	textlabel.Text = MName.."["..MRank.."]"
end

local DealDamage = function(Enemy,module, mob)
	local debounce = false

	mob.Torso.Touched:Connect(function(hit)
		if (Enemy.Health < 1) then return end
		if debounce then return end
		debounce = true
		Damage(hit, module)
		task.wait(.7)
		debounce = false
	end)
end
  
local OnDied = function(Enemy, module, mob)
	Enemy.Died:Connect(function()
		coroutine.wrap(Respawn)(module, mob) -- Not respawning
		coroutine.wrap(Award)(mob, Enemy, module)
		TeleportOnKill(module,Enemy)
	end)
end

local Follow = function(Enemy, _M)
	while _M.FollowDelay do
		local target = FindTarget(_M, Enemy)
		print(target) -- returning nil
		if target then
			Enemy.Humanoid:MoveTo(target.Position)
		end
	end
end

local function LoadCharacter(Enemy, _M, instance)
	Attributes(Enemy, _M)
	Follow(Enemy,_M)
	OnDied(Enemy, _M, instance)
	coroutine.wrap(DealDamage)(Enemy, _M, instance)
end

for _,v in pairs(game:GetService("CollectionService"):GetTagged("Mobs")) do
	if (not v:IsA("Model")) then return end
	if (not require(v.MobConfig)) then return end
	if not v:FindFirstChild("Enemy") then return end
	local Enemy = v.Enemy :: Humanoid
	local _M = require(v.MobConfig)
	LoadCharacter(Enemy,_M,v)
end

mobs.ChildAdded:Connect(function(c)
	if not c:IsA("Model") then return end
	if not c:FindFirstChild("Enemy") then return end
	local Enemy = c:FindFirstChild("Enemy")
	local _M = require(c.MobConfig)
	LoadCharacter(Enemy, _M, c)
end)

I don’t know if the problem is outside the function but please help me I am trying to fix that for like a day.

Try using HumanoidRootPart, it is always better because R6 and R15 avatars both contain a HumanoidRootPart.

1 Like

Also it shows an error: Script timeout: exhausted allowed execution time.

Line 100, 111, 122

function FindTarget(_M, Enemy)
	local maxDistance = _M.FollowDistance
	local mob = Enemy.Parent
        local target;
	for _, v in pairs(game.Players:GetPlayers()) do
		if v.Character and v.Character:FindFirstChild("Humanoid") then
			local HumanoidRootPart= v.Character:FindFirstChild("HumanoidRootPart")
			if HumanoidRootPart and (HumanoidRootPart.Position - mob.HumanoidRootPart.Position).Magnitude <= maxDistance then
				target = HumanoidRootPart
				maxDistance = (HumanoidRootPart.Position - mob.HumanoidRootPart.Position).Magnitude
			end
		end
        task.wait(.1)
        return target;
	end
end

It should work now, also made it find and return the CLOSEST target, not just first target found in distance.

1 Like

Didn’t work :frowning:
Maybe because of the error I showed up before? Script timeout: exhausted allowed execution time.

How does it not work? What is happening? Can you show me your output?

In while loop, also the enemy is right on the right.

Is your player within the max distance?
Print the magnitude and max distance to debug.

1 Like

It is not even printing, just like if it won’t reaching that

You need to give more context. These replies are very broad, where are you printing it?

function FindTarget(_M, Enemy)
	local maxDistance = _M.FollowDistance
	local mob = Enemy.Parent
        print(mob, _M, Enemy, HumanoidRootPart and (HumanoidRootPart.Position - mob.HumanoidRootPart.Position).Magnitude)
        local target;
	for _, v in pairs(game.Players:GetPlayers()) do
		if v.Character and v.Character:FindFirstChild("Humanoid") then
			local HumanoidRootPart= v.Character:FindFirstChild("HumanoidRootPart")
			if HumanoidRootPart and (HumanoidRootPart.Position - mob.HumanoidRootPart.Position).Magnitude <= maxDistance then
				target = HumanoidRootPart
				maxDistance = (HumanoidRootPart.Position - mob.HumanoidRootPart.Position).Magnitude
			end
		end
        task.wait(.1)
        return target;
	end
end

^Try that, it should print nil or your character is not in distance.

it is not printing anything. …