Testing Style - Studio Local Server with 2 players.

Script Location/Type - Regular script in the NPC

Output - https://ibb.co/8r5BN1m

Outcome - The NPC will spawn, and walk to its goal as expected, however, I want them to break their path if they detect another humanoid and go to attack it, and then continue down its path. Once it reaches its goal however it will stop and then the game will freeze and they'll move slightly and the output shows what I posted in the screenshot and they will stand there without doing anything

Code -

--Main body parts
local myRoot = script.Parent:WaitForChild("Torso")
local myHuman = script.Parent:WaitForChild("Humanoid")
local rightHand = script.Parent:WaitForChild("Right Arm")
local upperTorso = script.Parent:WaitForChild("Torso")
local team = myHuman.Team.Value

--Weapon
local sword = script.Parent:WaitForChild("Sword")
local swordWeld = sword:WaitForChild("SwordWeld")

--Sounds
local lungeSound = sword:WaitForChild("Lunge")
local slashSound = sword:WaitForChild("Slash")
local unsheathSound = sword:WaitForChild("Unsheath")

--AI Booleans
local attackCool = true
local swordHolstered = false
local chasing = false
local pathFailCount = 0 

--Animation
local leftSlash = script.Parent:WaitForChild("LeftSlash")
local leftSlashAnimation = myHuman:LoadAnimation(leftSlash)
leftSlashAnimation.Priority = Enum.AnimationPriority.Action

local rightSlash = script.Parent:WaitForChild("RightSlash")
local rightSlashAnimation = myHuman:LoadAnimation(rightSlash)
rightSlashAnimation.Priority = Enum.AnimationPriority.Action

--Respawn
local clone = script.Parent:Clone()

function getUnstuck()
	myHuman:Move(Vector3.new(math.random(-1,1),0,math.random(-1,1)))
	wait(0.3)
end

function wander()
	local xRand = math.random(-50,50)
	local zRand = math.random(-50,50)
	local goal = myRoot.Position + Vector3.new(xRand,0,zRand)
	local path = game:GetService("PathfindingService"):CreatePath()
	path:ComputeAsync(myRoot.Position, goal)
	if path.Status == Enum.PathStatus.Success then
		pathFailCount = 0
		myHuman.WalkSpeed = 10
		local waypoints = path:GetWaypoints()
		for i,v in ipairs(waypoints) do
			if v.Action == Enum.PathWaypointAction.Jump then
				myHuman.Jump = true
			end
			myHuman:MoveTo(v.Position)
			if i % 5 == 0 then
				if findTarget() then
					break
				end
			end
			local moveSuccess = myHuman.MoveToFinished:Wait()
			if not moveSuccess then
				break
			end
		end
	else
		pathFailCount = pathFailCount + 1 
		if pathFailCount > 10 then
			pathFailCount = 0
			getUnstuck()
		end
	end
end

function findTarget()
	local dist = 200
	local target = nil 
	for i,v in ipairs(workspace:GetChildren()) do
		local human = v:FindFirstChild("Humanoid")
		local torso = v:FindFirstChild("Torso") or v:FindFirstChild("HumanoidRootPart")
		if human and torso and v.Name ~= script.Parent.Name and v.Humanoid.Team.Value ~= team then
			if (myRoot.Position - torso.Position).Magnitude < dist and human.Health > 0 then
				target = torso
				dist = (myRoot.Position - torso.Position).Magnitude
			end
		end
	end
	return target
end

function checkSight(target)
	local ray = Ray.new(myRoot.Position, (target.Position - myRoot.Position).Unit * 200)
	local hit,position = workspace:FindPartOnRayWithIgnoreList(ray, {script.Parent})
	if hit then
		if hit:IsDescendantOf(target.Parent) then
			return true
		end
	end
	return false
end

function checkHeight(target)
	if math.abs(myRoot.Position.Y - target.Position.Y) < 1 then
		return true
	end
	return false
end

function checkDirect(target)
	if checkSight(target) and checkHeight(target) and (myRoot.Position - target.Position).Magnitude < 30 then
		return true
	end
	return false
end

function attack(target)
	if attackCool == true then
		attackCool = false
		myHuman:MoveTo(target.Position)
		
		local attackAnim = math.random(2)
		if attackAnim == 1 then
			slashSound:Play()
			leftSlashAnimation:Play()
		else
			lungeSound:Play()
			rightSlashAnimation:Play()
		end
		
		local human = target.Parent.Humanoid
		human:TakeDamage(math.random(20,30))
		
		if human.Health < 1 then
			wait(0.3)
		end
		
		spawn(function() wait(1) attackCool = true end)
	end
end

function holsterSword()
	if swordHolstered == false then
		swordHolstered = true
		
		unsheathSound:Play()
		
		swordWeld.Part1 = nil
		sword.CFrame = upperTorso.CFrame * CFrame.new(0,0,0.7) * CFrame.Angles(math.rad(90),math.rad(-45),math.rad(0))
		swordWeld.Part1 = upperTorso
	end
end

function drawSword()
	if swordHolstered == true then
		swordHolstered = false
		
		unsheathSound:Play()
		
		swordWeld.Part1 = nil
		sword.CFrame = rightHand.CFrame * CFrame.new(0,0,-2) * CFrame.Angles(0,math.rad(180),math.rad(90))
		swordWeld.Part1 = rightHand
	end
end

function pathToTarget(target)
	local path = game:GetService("PathfindingService"):CreatePath()
	path:ComputeAsync(myRoot.Position,target.Position)
	if path.Status == Enum.PathStatus.Success then
		pathFailCount = 0
		local waypoints = path:GetWaypoints()
		for i,v in ipairs(waypoints) do
			if v.Action == Enum.PathWaypointAction.Jump then
				myHuman.Jump = true
			end
			spawn(function()
				wait(0.5)
			myHuman:MoveTo(v.Position)
			local moveSuccess = myHuman.MoveToFinished:Wait()
			if not moveSuccess then 
			end
			if i % 5 == 0 then
				if checkDirect(target) then
				end
				if target ~= findTarget() then
				end
			end
			if (waypoints[#waypoints].Position - target.Position).Magnitude > 30 then
			end
			end)
		end
	end
end


function chase(target)
	myHuman.WalkSpeed = 20
	chasing = true
	myHuman:MoveTo(target.Position)
end

myHuman.Died:Connect(function()
	sword.CanCollide = true
	wait(15)
	clone.Parent = workspace
	game:GetService("Debris"):AddItem(script.Parent,0.1)
end)

function WalkTargetDestination()
	local destination = game.Workspace:FindFirstChild("map1").DestinationWB.Position
	local goal = destination
	local path = game:GetService("PathfindingService"):CreatePath()
	
	path.Blocked:Connect(function()
	print("Break!")
    breakPath = true
end)
	
path:ComputeAsync(myRoot.Position, destination)
if path.Status == Enum.PathStatus.Success then
	breakPath = false
				
	local waypoints = path:GetWaypoints()
        local wastedTime = 0
	for _, waypoint in pairs(waypoints) do	
		repeat
                        wastedTime = wastedTime + 0.25
			if(waypoint.Action == Enum.PathWaypointAction.Jump) then
				myHuman.Jump = true
			end
						
			 if breakPath == true then break end
			myHuman:MoveTo(waypoint.Position)
			wait()
		until (myRoot.Position - waypoint.Position).magnitude < 8 or breakPath == true
	end
end
end

function main()
	chasing = false 
	myHuman.WalkSpeed = 16
	local target = findTarget()
	if target then
		local targetDistance = (myRoot.Position - target.Position).Magnitude
		if targetDistance > 30 then
			holsterSword()
		else
			drawSword()
		end
		if checkDirect(target) then
			if targetDistance > 3 then
				chase(target)
			end
			if targetDistance < 6 then
				attack(target)
			end
		elseif checkSight(target) and math.abs(myRoot.Position.X - target.Position.X) < 1 and 
			math.abs(myRoot.Position.Z - target.Position.Z) < 1 then
		else
			pathToTarget(target)
		end
	else
		holsterSword()
		WalkTargetDestination()
		repeat until target
		end
	end

while wait(1) do
	if myHuman.Health < 1 then
		break
	end
	main()
end


Any help is appreciated! Thank you in advance.

2 comments

0

I think you might be calling the function main() while defining it. You need to add another end.

0

It says it expected but instead got end. Perhaps you could specify where in case i'm doing this wrong?