Tweening PivotTo() on a ServerScript for NPCs

My NPC is supposed to face the player when interacted and I have it working, but I would like it to tween smoothly.

I have tried looking at other posts, but none of them helped me because my situation is different. My NPCs are handled on a serverscript that runs different scripts depending on the NPCs name (stored in a table) e.g. Civilian, Suspicious Civilian. But it didn’t help my problem. Additionally, it would work for only one NPC, but make the other NPC of the same name bounce around the player.

A simple way of doing this like a tween is lerping. You can use :PivotTo() with a lookat cframe to face your NPC’s toward the player or whatever you want them to look at. could you give a little more context as to what exactly you are doing to all of the other NPC’s that may be affecting their position and causing the unwanted bouncing?

maybe that “one” npc that works with ur tween is the only one that have anchored enabled?

Neither one of them are anchored. They have wandering behavior that I am yet to implement properly.

A raycast from a tool sends a remote to the server, and the server tries to find the NPC with that name. It will then run the code for the NPC with that name on that NPC.

That is what is happening, but I’m not too sure what the issue could possibly be.

can u record a video of it?, cuz there is some reason, maybe the first frame of tweening got cancelled because the physics simulation changes the cframe (tween service stops the progress whenever the property gets overwritten by something else), try anchoring the npc humanoidrootpart before tweening them, also try to put prints along the way to test if the script even successfully locates the npc with the given name

I am completely stuck on what to do

you’re trying to get the npc with the same name to go in a circle around the player while bouncing, right?

local function LookAtFunc(Character : TheNPC, Target : Position)
	if Character.PrimaryPart then --just make sure the character's HRP has loaded
		local chrPos = Character.PrimaryPart.Position --get the position of the HRP
		local tPos = Target --get the position of the target
		local modTPos = (chrPos - tPos).Unit * Vector3.new(1,0,1) --mask out the Y axis
		local upVector = Character.PrimaryPart.CFrame.UpVector
		local newCF = CFrame.lookAt(chrPos, chrPos + modTPos, upVector) * CFrame.fromAxisAngle(Vector3.new(0, 1, 0), math.pi) --set the HRP's CFrame to our result, thus moving the character!
		return newCF
	end
end

local GetGoalCF = LookAtFunc(NPC, MyChar.PrimaryPart.Position)

game:GetService("TweenService"):Create(NPC.PrimaryPart, TweenInfo.new(Duration, Enum.EasingStyle.Linear), {CFrame = GetGoalCF}):Play()

also try anchoring the primarypart of the npc first before u tween, then unanchoring it again once the tween has finished

The tween works now, but it is still not working for the other NPC.

Notice how the other NPC turns, but not the one I’m interacting with.

If you’d like, I can show the code that manages NPC behavior if it helps.

Yes, we need the code to fix it :slight_smile:

then ur inserting the wrong npc into the function

yea u can show the code, il read it


local function LookAtFunc(Character : TheNPC, Target : Position)
	if Character.PrimaryPart then
		local chrPos = Character.PrimaryPart.Position
		local tPos = Target --get the position of the target
		local modTPos = (chrPos - tPos).Unit * Vector3.new(1,0,1)
		local upVector = Character.PrimaryPart.CFrame.UpVector
		local newCF = CFrame.lookAt(chrPos, chrPos + modTPos, upVector) * CFrame.fromAxisAngle(Vector3.new(0, 1, 0), math.pi) 
		return newCF
	end
end



local function TurnToPlayer(player, character, waitingTime)
	local GetGoalCF = LookAtFunc(character, player.Character.PrimaryPart.Position)
	game:GetService("TweenService"):Create(character.PrimaryPart, TweenInfo.new(0.5, Enum.EasingStyle.Linear), {CFrame = GetGoalCF}):Play()
	task.wait(waitingTime)
end

NPCManager.NPCs = {
	["Base Pedestrian"] = function(player, npc, gunActive)
		local sound
		local outcome
		local AnimOutcome
		local Animating
		local humanoid = npc:WaitForChild("Humanoid")
		print("...")
		local waitingTime = math.random(3, 5)
		TurnToPlayer(player, npc, waitingTime)
		local decisionMade = math.random(1,2)
		if decisionMade == 1 then
			print("Sure thing!")
			outcome = true
			sound = Var1SureSounds
			AnimOutcome = YesAnims
		else
			print("No way")
			outcome = false
			sound = Var1refuseSounds
			AnimOutcome = NoAnims
		end
		local playing = sound[math.random(1,#sound)]
		local animatingT = AnimOutcome
		Animating = humanoid.Animator:LoadAnimation(animatingT)
		Animating.Priority= Enum.AnimationPriority.Action
		playing:Play()
		playing.Ended:Wait()
		task.wait(0.5)
		ReceivedEvent:FireClient(player, outcome)
	end,

}

local function onRemoteTriggered(player, npcID, gunActive)
	print(player.Name .. "'s signal was received, now triggering script for " .. npcID.Name)
	local npc = game.Workspace:FindFirstChild(npcID.Name)
	if npc and NPCManager.NPCs[npcID.Name] then
		print("Script running!")
		print(player)
		print(npc)
		NPCManager.NPCs[npcID.Name](player, npc, gunActive)
	end
end

AskedEvent.OnServerEvent:Connect(onRemoteTriggered)

Note that I am still working on the script, but I would like the issue to be solved first.

seems fine to me, i believe its ur local script that is sending the id of the wrong npc

also, u dont need to give them ids if they exist in workspace anyway, ur localscript can send the npc directly without needing the id stuff

Can you elaborate on what that means?

Also, the NPCs will be cloned multiple times.

so the id will be duplicated aswell, maybe thats why its picking the first npc with the same id (:FindFIrstChild) but theres multiple of them, so first npc first serve

instead of giving them ids, try sending the npc itself through remote event, as long as it exist both in client and server (such as workspace) u can send it through remote events

Can you elaborate on that? I don’t understand.

show me the local script incharge of picking which npc to remote event