Okay, so I’ve recently been struggling with the following problems trying to make a proper NPC chasing system:
- The NPC starts stuttering once I keep walking as it recalculates the path every time I change my position further than a few studs.
- It starts teleporting randomly while chasing me without creating a path which I could not really find out why still appears to happen.
The following is the AI script:
local players = game:GetService("Players")
local teams = game:GetService("Teams")
local SSS = game:GetService("ServerScriptService")
local module = require(script.Parent)
local globalFunctions = require(SSS.globalFunctions)
local simplePath = require(game:GetService("ServerStorage").simplePath)
local SCP = script.Parent.Parent
local pathfinding = game:GetService("PathfindingService")
local path = pathfinding:CreatePath({
AgentRadius = 3.5,
AgentHeight = 6,
AgentCanJump = false,
})
for i, part in pairs(script.Parent:GetChildren()) do
if part:IsA("BasePart") then
part:SetNetworkOwner(nil)
end
end
while task.wait(1) do
if(module.settings.on == false) then continue end
local closestChar = module.findNearestPathable()
if(not closestChar) then
warn("Could not find closestChar")
continue
end
local previousPosition = nil
local isThereACloseChar = module.findNearestUsingRay(closestChar)
local function shouldWalkInsteadOfPathing(destination, character)
if(not destination) or (typeof(destination) ~= "Vector3") then
return false
end
local distance = (SCP.HumanoidRootPart.Position-destination).Magnitude
local YDifference = math.abs(destination.Y-SCP.HumanoidRootPart.Position.Y)
local raycastParameters = RaycastParams.new()
raycastParameters.FilterType = Enum.RaycastFilterType.Exclude
raycastParameters.FilterDescendantsInstances = {SCP, character}
local startPosition = SCP.HumanoidRootPart.Position
local destinationPosition = (destination-startPosition).Unit * distance
local raycastHitStatus = module.raycastHitCheck(startPosition, destination, distance, raycastParameters)
print("raycastHitStatus:")
print(raycastHitStatus)
--print("Raycast:")
--print(raycastHitStatus)
local status = (distance < module.settings.minimumDistanceToWalkDirectly) and (YDifference < module.settings.maximumYDifferenceToWalkDirectly) and raycastHitStatus == nil
-- print("status: "..tostring(status))
return status
end
local function reCalculatePath(destination)
path:ComputeAsync(SCP.HumanoidRootPart.Position, destination)
print("Computated path")
if(path.Status == Enum.PathStatus.NoPath) then
return warn("Could not generate the path!")
end
--print("Generated the path successfully.")
end
local previousPosition = nil
repeat
local closestCharUpdate = workspace:FindFirstChild(closestChar.Name)
local hasTurnedIntoSCP
if(not closestCharUpdate) or (closestCharUpdate ~= closestChar) then
break
end
local currentDistance = (SCP.HumanoidRootPart.Position-closestCharUpdate.HumanoidRootPart.Position).Magnitude
local shouldWalkDirectly = shouldWalkInsteadOfPathing(closestCharUpdate.HumanoidRootPart.Position)
isThereACloseChar = module.findNearestUsingRay(closestChar, currentDistance)
local newPosition = closestCharUpdate.HumanoidRootPart.Position
if shouldWalkDirectly then
if(previousPosition) and (previousPosition-newPosition).Magnitude < 2 then
task.wait(0.08)
continue
end
task.wait(0.08)
print("The SCP will just walk instead of generating a path.")
SCP.Humanoid.WalkSpeed = 16
SCP.Humanoid:MoveTo(closestCharUpdate.HumanoidRootPart.Position, closestCharUpdate.HumanoidRootPart)
previousPosition = newPosition
continue
end
reCalculatePath(closestCharUpdate.HumanoidRootPart.Position)
if(path.Status == Enum.PathStatus.NoPath) then
continue
end
local waypoints = path:GetWaypoints()
local nextWaypoint = 2
if(#waypoints) < 2 then
break
end
print("Waypoint size: "..tostring(#waypoints))
repeat
local nextWaypointToWalk = waypoints[nextWaypoint]
SCP.Humanoid.WalkSpeed = 16
SCP.Humanoid:MoveTo(nextWaypointToWalk.Position)
print("Moving to "..tostring(nextWaypointToWalk.Position))
SCP.Humanoid.MoveToFinished:Wait()
nextWaypoint += 1
until (not closestChar) or shouldWalkInsteadOfPathing(closestCharUpdate.HumanoidRootPart.Position) or nextWaypoint == #waypoints+1 or (waypoints[#waypoints].Position-closestCharUpdate.HumanoidRootPart.Position).Magnitude > 3
until (not closestChar) or isThereACloseChar --(not module.isLooking(closestChar.Head, noob.Head.Position))
end