Hello Hello hop yall are well : )
I recently started playing around with the “advanced npc system” which can be found here: https://www.youtube.com/watch?v=_DOGUy_kFCg
I want the NPCs to not only stay a reasonable distance from me but also from each other. Here is the original:
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local NPC = script.Parent
local stopDistance = 12 -- Do not put this value below 5, or the NPC will break.
local followDistance = 120
local normalSpeed = 12
local fastSpeed = 30
local backupSpeed = 20
local walkingAnim = script:WaitForChild("WalkAnim")
local sprintAnim = script:WaitForChild("SprintAnim")
local idleAnim = script:WaitForChild("IdleAnim")
local reverseAnim = script:WaitForChild("ReverseWalkAnim")
local idleTrack = NPC.Humanoid:LoadAnimation(idleAnim)
local sprintTrack = NPC.Humanoid:LoadAnimation(sprintAnim)
local walkTrack = NPC.Humanoid:LoadAnimation(walkingAnim)
local reverseTrack = NPC.Humanoid:LoadAnimation(reverseAnim)
idleTrack:Play()
NPC.Humanoid.WalkSpeed = normalSpeed
local function getNearestPlayer()
local nearestPlayer
local shortestDistance = math.huge
for _, player in pairs(Players:GetPlayers()) do
if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
local distance = (player.Character.HumanoidRootPart.Position - NPC.HumanoidRootPart.Position).magnitude
if distance < shortestDistance then
shortestDistance = distance
nearestPlayer = player
end
end
end
return nearestPlayer, shortestDistance
end
RunService.Heartbeat:Connect(function()
local nearestPlayer, distance = getNearestPlayer()
if nearestPlayer and distance <= followDistance then
local playerPosition = nearestPlayer.Character.HumanoidRootPart.Position
local npcPosition = NPC.HumanoidRootPart.Position
NPC.HumanoidRootPart.CFrame = CFrame.new(npcPosition, playerPosition)
if distance > stopDistance + 2 then
NPC.Humanoid:MoveTo(nearestPlayer.Character.HumanoidRootPart.Position)
if distance >= followDistance * 0.35 then
if not sprintTrack.IsPlaying then
sprintTrack:Play()
end
walkTrack:Stop()
reverseTrack:Stop()
idleTrack:Stop()
NPC.Humanoid.WalkSpeed = fastSpeed
elseif distance <= stopDistance * 1.5 then
if not walkTrack.IsPlaying then
walkTrack:Play()
end
sprintTrack:Stop()
reverseTrack:Stop()
idleTrack:Stop()
NPC.Humanoid.WalkSpeed = normalSpeed
end
elseif distance < stopDistance - 2 then
NPC.Humanoid.WalkSpeed = normalSpeed
local directionToBackUp = (npcPosition - playerPosition).Unit * backupSpeed
local targetPosition = npcPosition + directionToBackUp
if (targetPosition - npcPosition).Magnitude > 0.1 then
NPC.Humanoid:MoveTo(targetPosition)
if not reverseTrack.IsPlaying then
walkTrack:Stop()
sprintTrack:Stop()
idleTrack:Stop()
reverseTrack:Play()
end
else
walkTrack:Stop()
sprintTrack:Stop()
reverseTrack:Stop()
if not idleTrack.IsPlaying then
idleTrack:Play()
end
end
else
NPC.Humanoid.WalkSpeed = normalSpeed
walkTrack:Stop()
sprintTrack:Stop()
reverseTrack:Stop()
if not idleTrack.IsPlaying then
idleTrack:Play()
end
end
else
NPC.Humanoid.WalkSpeed = normalSpeed
walkTrack:Stop()
sprintTrack:Stop()
reverseTrack:Stop()
if not idleTrack.IsPlaying then
walkTrack:Stop()
sprintTrack:Stop()
reverseTrack:Stop()
idleTrack:Play()
end
end
end)
And here is my modified version where you can see I basically just copied the player part but made it work with NPCs in the folder:
I’m not sure how to implement both the player part and the NPC part at the same time without it just picking one over the other, and with more than one other NPC this problem gets harder.
Any ideas?
Thanks, dev