Advertisement
valentine1

NPC

May 31st, 2025
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.84 KB | Source Code | 0 0
  1. local behaviour = { }
  2. behaviour.__index = behaviour
  3.  
  4. local plrService = game:GetService("Players")
  5. local runService = game:GetService("RunService")
  6. local pfnService = game:GetService("PathfindingService")
  7.  
  8. local NPCs, Folder = { }, game.Workspace:WaitForChild("NPCs")
  9.  
  10. function behaviour.new(rig)
  11.     local self = setmetatable({ }, behaviour)
  12.    
  13.     for _, part in (rig:GetDescendants()) do
  14.         if part:IsA("BasePart") then
  15.             part:SetNetworkOwner(nil)
  16.         end
  17.     end
  18.    
  19.     self.Character = rig
  20.     self.Humanoid = rig.Humanoid
  21.     self.HumanoidRoot = rig.HumanoidRootPart
  22.    
  23.     self.Target = nil
  24.     self.Path = nil
  25.     self.Goal = nil
  26.     self.Step = nil
  27.     self.IsMoving = false
  28.     self.IsDated = false
  29.    
  30.     self.Thread = nil
  31.    
  32.     return self
  33. end
  34.  
  35. function behaviour:getPlayerPath(target, origin)
  36.     local path = pfnService:CreatePath({
  37.         AgentCanJump = true,
  38.         AgentCanClimb = true,
  39.         AgentRadius = 3,
  40.     })
  41.     local goal = target.Character:WaitForChild("HumanoidRootPart")
  42.    
  43.     local success, error = pcall(function()
  44.         path:ComputeAsync(origin or self.HumanoidRoot.Position, goal.Position)
  45.     end)
  46.    
  47.     if not success or path.Status ~= Enum.PathStatus.Success then
  48.         return nil
  49.     end
  50.    
  51.     return path
  52. end
  53.  
  54. function behaviour:getClosestPlayer()
  55.     local target = {name = nil; dist = nil;}
  56.    
  57.     for index, player in pairs(plrService:GetPlayers()) do
  58.         if player.Character then
  59.             local HRP = player.Character:WaitForChild("HumanoidRootPart")
  60.             local distance = (self.HumanoidRoot.Position - HRP.Position).Magnitude
  61.  
  62.             if target["dist"] == nil or distance <= target["dist"] then
  63.                 target["name"] = player.Name
  64.                 target["dist"] = distance
  65.             end
  66.         end
  67.     end
  68.    
  69.     return target["name"] and plrService:FindFirstChild(target["name"]) or nil
  70. end
  71.  
  72. function behaviour:usePlayerPath()
  73.     self.IsMoving = true
  74.     local waypoints
  75.    
  76.     if self.Path then
  77.         waypoints = self.Path:GetWaypoints()
  78.     else
  79.         self.Path = self:getPlayerPath(self.Target)
  80.        
  81.         if not self.Path then
  82.             task.wait()
  83.             self:usePlayerPath()
  84.             return
  85.         end
  86.        
  87.         waypoints = self.Path:GetWaypoints()
  88.     end
  89.    
  90.     for i, waypoint in ipairs(waypoints) do
  91.         if i ~= 1 or waypoint.Action == Enum.PathWaypointAction.Jump or self.Humanoid:GetState() == Enum.HumanoidStateType.Climbing then
  92.             self.Step = waypoint.Position
  93.             self.Humanoid:MoveTo(waypoint.Position)
  94.  
  95.             if waypoint.Action == Enum.PathWaypointAction.Jump then
  96.                 self.Humanoid.Jump = true
  97.             end
  98.  
  99.             local allow = 0
  100.             while (self.HumanoidRoot.Position - waypoint.Position).magnitude > 3.8 and allow < 5 do
  101.                 allow = allow + 1
  102.                 game:GetService("RunService").Heartbeat:wait()
  103.             end
  104.  
  105.             if self.IsDated then
  106.                 self.IsDated = false
  107.                 self:usePlayerPath()
  108.                 return
  109.             end
  110.         end
  111.     end
  112.    
  113.     self.IsMoving = false
  114. end
  115.  
  116. runService.Stepped:Connect(function()
  117.     for index, NPC in ipairs(NPCs) do
  118.         local self = NPC
  119.        
  120.         self.Target = self:getClosestPlayer()
  121.  
  122.         if self.Target and self.Target.Character then
  123.             if not self.Goal or (self.Target.Character.HumanoidRootPart.Position - self.Goal).Magnitude > 0.65 then
  124.                 self.Goal = self.Target.Character.HumanoidRootPart.Position
  125.  
  126.                 if self.Humanoid:GetState() == Enum.HumanoidStateType.Climbing and self.Humanoid.MoveDirection.Magnitude > 0 then
  127.                     if self.Target.Character.Humanoid:GetState() ~= Enum.HumanoidStateType.Climbing then
  128.                         return
  129.                     end
  130.                 end
  131.  
  132.                 if self.IsMoving then
  133.                     self.IsDated = true
  134.                     self.Path = self:getPlayerPath(self.Target, self.Step)
  135.                     return
  136.                 end
  137.  
  138.                 self.Path = self:getPlayerPath(self.Target)
  139.  
  140.                 if self.Path then
  141.                     self:usePlayerPath()
  142.                 end
  143.             end
  144.         else
  145.             self.Humanoid:MoveTo(self.HumanoidRoot.Position)
  146.         end
  147.     end
  148. end)
  149.  
  150. for index, NPC in pairs(Folder:GetChildren()) do
  151.     if NPC:IsA("Model") and NPC:FindFirstChild("Humanoid") then
  152.         local object = behaviour.new(NPC)
  153.         table.insert(NPCs, object)
  154.     end
  155. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement