I’m debating between two approaches for NPC movement in my game, my biggest concern is memory usage. The first approach would be to just have every NPC on a loop of constant movement. The other is to have a touch system, where the player touches an inner ring and the NPC starts moving, and then touches and outer ring to make the NPC stop.
My concern with the constant loop is it could use too much memory. Video below: robloxapp-20240121-0824109.wmv (974.1 KB)
My concern with the ring-touch system is it doesn’t always work properly, NPCs will sometimes do their walk animation in place without movement, or their movements will be abbreviated before they turn around. Video below: robloxapp-20240121-0821355.wmv (5.1 MB)
If you are worried about the inconsistency between the two listed options, why not make a hybrid? It could use the loop but have the NPC check less often than you would using just the loop. And at the same time it can have the touch system.
Could you elaborate on what your game is about? If so I may be able to help form some code that would be a laggless-consistent solution.
Thanks for the response! My game is a RPG with monster catching and questing. After more testing, it seems that the animations won’t work in my game at all, the models glide back and forth, but they don’t use the animations. And I know the animations do work from the videos of the test area in the first post.
I tried having the NPCs with their own individual script, and a Server script that managed the movement for all of them. I’m thinking my game map is just too big? The game is fully finished, aside from this…but I’m starting to think its best to have stationary NPCs than delay it even further than it has been.
Here’s the server script that moves them all:
local ServerScriptService = game:GetService("ServerScriptService")
local Workspace = game:GetService("Workspace")
local Animation = Instance.new('Animation')
Animation.AnimationId = 'rbxassetid://16015740674'
local MoveDistance = 10
local function waitUntilFinished(Humanoid, AnimationTrack)
repeat
wait()
until Humanoid.MoveToFinished:Wait()
AnimationTrack:Stop()
end
local function MoveToDestination(Humanoid, AnimationTrack, Destination)
AnimationTrack:Play()
Humanoid:MoveTo(Destination)
waitUntilFinished(Humanoid, AnimationTrack)
end
local function SetupNPC(NPC)
local Humanoid = NPC:FindFirstChildOfClass("Humanoid")
if not Humanoid then
return
end
local AnimationTrack
local AnimationController = NPC.Model:FindFirstChild("AnimationController")
if AnimationController then
AnimationTrack = AnimationController:LoadAnimation(Animation)
else
AnimationTrack = Humanoid:LoadAnimation(Animation)
end
local InitialPosition = NPC.PrimaryPart.Position
local Destination1 = InitialPosition + Vector3.new(MoveDistance, 0, 0)
local Destination2 = InitialPosition - Vector3.new(MoveDistance, 0, 0)
while true do
MoveToDestination(Humanoid, AnimationTrack, Destination1)
wait(1)
MoveToDestination(Humanoid, AnimationTrack, Destination2)
wait(1)
end
end
-- NPC Setup
local NPCsFolder = Workspace:WaitForChild("NPCs")
local NPCs = NPCsFolder:GetChildren()
for _, NPC in pairs(NPCs) do
if NPC:IsA("Model") then
spawn(function()
SetupNPC(NPC)
end)
end
end
I would make it to where they only move within a certain distance from the player. Kinda like they see the player and begin moving. That could solve most of your lag!
(If you do this it’s smart to have them check for the player every 3-6 seconds – this way not too many monsters or npcs are checking at the same time)