Hello, i hope you all are having a good day.
So my issue is, i have npcs which chase players down, but the hum:moveto is heavily delayed.
I have used this script to set the npc’s network owner to nil:
module.SetNetworkOwner = function(Character)
for i,v in pairs(Character:GetDescendants()) do
if v:IsA("Part") or v:IsA("BasePart") then
v.Massless = true
v.CollisionGroup = "Players"
pcall(function()
if v.Anchored == false then
v:SetNetworkOwner(nil)
end
end)
end
end
end
it is functioning, from what i can tell, since all the npcs are highlighted in white, when i turn on “are owners shown”.
the pathfinding script:
local module = {}
local PathfindingService = game:GetService("PathfindingService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local TweeenService = game:GetService("TweenService")
local Both = ReplicatedStorage:WaitForChild("Modules"):WaitForChild("Both")
local StatusHandler = require(Both:WaitForChild("StatusHandler"))
local Utilities = require(Both:WaitForChild("Utilities"))
local Pathfinding = require(script.Parent.Parent)
local Raycastparams = RaycastParams.new()
Raycastparams.FilterType = Enum.RaycastFilterType.Include
Raycastparams.FilterDescendantsInstances = {workspace.Map}
local CheckFloor = Utilities.CheckFloor
local CheckLocation = Utilities.CheckLocation
local SetNetworkOwenr = Utilities.SetNetworkOwner
local Distance = Utilities.Distance
local CreatePath = Pathfinding.CreatePath
local Info = TweenInfo.new(0.2,Enum.EasingStyle.Sine,Enum.EasingDirection.Out,0,false,0)
local Players = workspace:WaitForChild("Players")
local Enemies = workspace:WaitForChild("Enemies")
local abs = math.abs
local huge = math.huge
local StraightIncrement = 1
-- Functions
local Types = {}
for i,v in pairs(script:GetChildren()) do
if v:IsA("ModuleScript") then
Types[v.Name] = require(v)
end
end
module.Setup = function(Character,Type)
local Hrt = Character:WaitForChild("HumanoidRootPart")
local Head = Character:WaitForChild("Head")
local Hum = Character:WaitForChild("Humanoid")
local Animator = Hum:WaitForChild("Animator")
local FindPath
local Radius = Hrt.Size.X + 0.5
local Path = PathfindingService:CreatePath(
{AgentRadius = Radius, AgentHeight = 5,AgentCanJump = true,AgentCanClimb = true,WaypointSpacing = 3}
)
spawn(function()
while task.wait(1.75) do
SetNetworkOwenr(Character)
end
end)
local Items = Pathfinding.Create(Character)
local CurrentTarget = Items.CurrentTarget
local Targetting = Items.Targetting
local IsAttacking = Items.IsAttacking
-- Vars
local Blocked = nil
local Reached = nil
local Changed = nil
local Waypoints = nil
local Died = false
local Find
local WhiteListFind = {}
local NewPath = nil
local Whitelist = {}
local AutoJump = false
local TargetWhitelist = {}
local Range = 0
local FollowPath = nil
local Waypoints = nil
local Destination = nil
local LastReached = os.clock()
local NextIndex = 1
local SF = Character:WaitForChild("SF")
local StatsFolder = SF:WaitForChild("Stats")
local WhitelistFolder = StatsFolder:WaitForChild("Whitelist")
TargetWhitelist = WhitelistFolder:GetChildren()
Range = StatsFolder.Range.Value
local AttackMod = Types[Type]
local TargetClose = function(PrimaryFind)
local PrimaryFindPos = PrimaryFind.Position
local Headpos = PrimaryFind.Parent.Head.Position
local CharHeadPos = Head.Position
local Dir = (Headpos - CharHeadPos)
local Unit = Dir.Unit
local Dis = Dir.Magnitude
local NewRay = workspace:Raycast(CharHeadPos,Unit * Dis, Raycastparams)
local YNitude = abs(PrimaryFindPos.Y - Hrt.Position.Y)
local Jp = Hum.JumpPower^2 / (2*workspace.Gravity)
local CeiledDis = math.ceil(Dis / StraightIncrement)
local Positions = {
[1] = {Position = Hrt.Position},
}
for i = 2,math.clamp(CeiledDis,2,9999) do
local Mp = math.min(StraightIncrement * i,Dis)
local NewWaypointPos = CharHeadPos + (Unit * Mp )
--print(i,NewWaypointPos)
Positions[i] = {Position = NewWaypointPos}
end
if NewRay == nil and YNitude < Jp then
FollowPath({Destination = Find,AutoJump = true,Waypoints = Positions})
return true
end
end -- does a direct path, if target is visible, instead of pathfinding.
local WallRayJump = function()
local Offset = 1
for i = 1,4 do
local HrtPos = Hrt.CFrame * CFrame.new(0,Offset,0)
Offset -= 0.5
local Dir = HrtPos.Position - (HrtPos * CFrame.new(0,0,-1)).Position
local Raycast = workspace:Raycast(Hrt.Position,-Dir.Unit * Dir.Magnitude,Raycastparams)
if Raycast then
if CheckFloor(Hrt) then
Hum:ChangeState(Enum.HumanoidStateType.Jumping)
end
end
end
end
local CheckWhitelist = function(Object)
if Object:FindFirstChild("Tags") == nil then print("notag") return false end
for i,v in ipairs(TargetWhitelist) do
if Object.Tags:FindFirstChild(v.Name) then
return true
end
end
return false
end
local FindPlayer = function(Character)
local Hrt = Character:FindFirstChild("HumanoidRootPart")
if Character == nil or Hrt == nil then return end
local Hrt = Character.HumanoidRootPart
local Closest = nil
local ToLoop = Players:GetChildren()
local Length = 0
for i,v in pairs(Whitelist) do
Length += 1
end
if Length >= #ToLoop then Whitelist = {} end
for i,v in pairs(Enemies:GetChildren()) do
table.insert(ToLoop,v)
end
for i,v in pairs(ToLoop) do
task.wait()
if v == Character or CheckWhitelist(v) then continue end
if v:FindFirstChild("Humanoid") == nil then continue end
if v.Humanoid.Health <= 0 then continue end
if Closest == nil and Whitelist[v] == nil then
Closest = v
elseif Closest then
local VRoot = v:FindFirstChild("HumanoidRootPart")
local ClosestRoot = Closest:FindFirstChild("HumanoidRootPart")
if not VRoot or not ClosestRoot then continue end
local Dis1 = (Hrt.Position - VRoot.Position).Magnitude
local Dis2 = (Hrt.Position - ClosestRoot.Position).Magnitude
if Dis1 < Dis2 and Whitelist[v] == nil then
Closest = v
end
end
end
return Closest
end
spawn(function()
if AttackMod then
spawn(function()
if AttackMod == nil or AttackMod.Setup == nil then warn(Character.Name .. "Not a valid setup") end
AttackMod.Setup(Character)
end)
end
end)
function FollowPath(Args)
Destination = Args.Destination
Waypoints = Args.Waypoints
AutoJump = Args.AutoJump
WallRayJump() -- jumps if blocked by wall
if Destination == nil then return end
if Destination:FindFirstChild("SF") == nil then return end
local Pos1 = Hrt.Position
local DestinationRoot = Destination.HumanoidRootPart
local Pos2 = DestinationRoot.Position
local WhiteListFind = {}
local NewDistance = Distance(Pos1,Pos2)
--Waypoints = createpath(Destination,Hrt,Hum,Range,Path)
local CurrentState = Hum:GetState()
if Waypoints == nil then task.wait(2) FindPath() return end
if CurrentState == Enum.HumanoidStateType.Climbing and os.clock() - LastReached <= 6.5 then task.wait(0.1) return end
--[[
if Waypoints ~= "Continue" then
for i,v in pairs(Waypoints) do
local Part = Instance.new("Part")
Part.Anchored = true
Part.Size = Vector3.new(0.5,0.5,0.5)
Part.CanCollide = false
Part.Transparency = 0.1
Part.Position = v.Position
Part.Parent = workspace.Effects
task.delay(0.5,function()
Part:Destroy()
end)
end
end]]
WallRayJump() -- jumps if blocked by wall
CurrentTarget.Value = Destination
if not Blocked then
Blocked = Path.Blocked:Connect(function(BlockedIndex)
if BlockedIndex >= NextIndex then
FindPath()
print("Blocked")
end
end)
end
local LastPos = DestinationRoot.Position
local DtAdd = 0
if not Changed then
Changed = RunService.Heartbeat:Connect(function(dt)
local PrimaryFind
local CurrentValue = CurrentTarget.Value
if os.clock() - LastReached >= 1.1 then
LastReached = os.clock()
FindPath()
return
end -- if not moved, since 0.8 seconds then recalculate path, if blocked will try to jump, as stated in the wallrayjump func
if CurrentTarget.Value then
PrimaryFind = CurrentValue:FindFirstChild("HumanoidRootPart")
else
return
end -- if therei s a target
if PrimaryFind == nil then return end
local PrimaryFindPos = PrimaryFind.Position
if not IsAttacking.Value and Targetting.Value then
if CheckFloor(Hrt) then
local HrtPos = Hrt.Position
local Pos = CFrame.lookAt(HrtPos,Vector3.new(PrimaryFindPos.X,HrtPos.Y,PrimaryFindPos.Z))
local Track = TweeenService:Create(Hrt,Info,{CFrame = Pos})
Track:Play()
else
Targetting.Value = false
IsAttacking.Value = false
end
end -- look at enemy if attacking, and not reloading
DtAdd += dt
if DtAdd < 0.2 then return end -- only checks every 0.2 seconds
DtAdd = 0
WhiteListFind = {}
local Distance = (Hrt.Position - LastPos).Magnitude
if AutoJump then
WallRayJump()
end -- jumps if collided with anything, which is decentdant of workspace.map
local FindClose = TargetClose(PrimaryFind) -- check the func
if FindClose then return end
WhiteListFind = {}
Find = FindPlayer(Character,WhiteListFind)
if Find and Find ~= CurrentValue then
FindPath()
end
if CurrentValue then
if CurrentValue.Humanoid.Health <= 0 then CurrentValue = nil end
if PrimaryFindPos ~= LastPos and (PrimaryFindPos - LastPos).Magnitude >= 10 then
FindPath()
end
end -- if currenttarget dies, or if they move 10 studs, will recalculate, enem and or path
LastPos = PrimaryFindPos
end)
end
if not Reached then
Reached = Hum.MoveToFinished:Connect(function(reached)
if Waypoints == nil then return end
if CurrentTarget.Value == nil then FindPath() return end
local Pos1 = Hrt.Position
local Pos2 = DestinationRoot.Position
local WaypointDex = Waypoints[NextIndex]
if WaypointDex == nil then FindPath() return end
-- print(Distance(Pos1,Pos2) < Range)
if not CheckLocation(Pos1,Pos2) and Distance(Pos1,Pos2) < Range then return end
if reached and NextIndex < #Waypoints then
NextIndex += 1
LastReached = os.clock()
local Next = Waypoints[NextIndex]
Hum:MoveTo(Next.Position)
if Next.Action == Enum.PathWaypointAction.Jump then
if CheckFloor(Hrt) then
Hum:ChangeState(Enum.HumanoidStateType.Jumping)
end
end
Targetting.Value = false
else
FindPath()
end
end)
end -- for when it reaches a new waypoint
NextIndex = 2 -- 1 is the starting pos
if Waypoints[NextIndex] then
local Pos1 = Hrt.Position
local Pos2 = DestinationRoot.Position
if CheckLocation(Pos1,Pos2) or Distance(Pos1,Pos2) >= Range then
if Waypoints[NextIndex].Action == Enum.PathWaypointAction.Jump then
if CheckFloor(Hrt) then
Hum:ChangeState(Enum.HumanoidStateType.Jumping)
end
end
LastReached = os.clock()
Hum:MoveTo(Waypoints[NextIndex].Position)
Targetting.Value = false
end
end -- starts the inital pathfinding loop.
end
FindPath = function()
WhiteListFind = {}
repeat
Find = FindPlayer(Character,WhiteListFind)
if Find then
local PrimaryFind = Find:FindFirstChild("HumanoidRootPart")
if PrimaryFind == nil then continue end
local FindClose = TargetClose(PrimaryFind)
if FindClose then return end
NewPath = CreatePath(PrimaryFind,Hrt,Hum,Range,Path)
FollowPath({Destination = Find,Waypoints = NewPath})
if NewPath == nil then
if Find then
WhiteListFind[Find] = true
end
end
end
task.wait()
until CurrentTarget.Value and NewPath
WhiteListFind = {}
end
FindPath()
-- attack
spawn(function()
while task.wait() do
if Died then
break
end
if CurrentTarget.Value == nil then
FindPath()
end
end
end)
-- Died
Hum:GetPropertyChangedSignal("Health"):Connect(function()
if Hum.Health <= 0 then
if Changed then
Changed:Disconnect()
end
if Blocked then
Blocked:Disconnect()
end
if Reached then
Reached:Disconnect()
end
Path:Destroy()
Died = true
end
end)
end
return module
the networkownerscript force runs every 3 seconds on the npc (maybe it shouldn’t)
this issue mainly happens when i spawn right next to them??
This issue mainly seems to happen when i spawn right next to the npcs. thanks for any responses!