AlignOrientation wont edit via LocalScript

Trying to make an NPC system and AlignOrientation doesnt work on a localscript. Ive tried instancing the alignorientation object from the client and everything else but it still doesnt work

local function EnemyFunc(v)

	local humanoid = v:WaitForChild("Humanoid")
	local detectEvent = v:FindFirstChild("Detect")
	local animator = humanoid:WaitForChild("Animator")

	local lastHealthValue = tonumber(humanoid.Health)
	local invulnerable = false


	task.defer(function()
		local diff
		local angle
		local humanoidRootPart = v:FindFirstChild("HumanoidRootPart")
		local AlignOrientation, attachment
		local closestPlayer, distance
		v.Humanoid.AutoRotate = false
		
		
		if humanoidRootPart then
			AlignOrientation = Instance.new("AlignOrientation")
			AlignOrientation.Mode = Enum.OrientationAlignmentMode.OneAttachment
			AlignOrientation.Responsiveness = 200
			AlignOrientation.Parent = humanoidRootPart
			attachment = Instance.new("Attachment")
			attachment.Parent = humanoidRootPart
			attachment.Position = Vector3.new(0,0,0)
			AlignOrientation.Attachment0 = attachment
		end

		
		runService.RenderStepped:Connect(function()
			closestPlayer, distance = getClosestPlayer(v)
			if closestPlayer and distance and AlignOrientation then
				diff = v.HumanoidRootPart.Position - closestPlayer.Character.PrimaryPart.Position
				--print(closestPlayer)
				angle = math.atan2(diff.X, diff.Z)
				AlignOrientation.CFrame = CFrame.Angles(0, angle, 0)
			end
		end)
	end)
end

heres my code. I dont understand why it runs on the server but not the client

Its also worth noting that the AlignOrientation Orientation value actually changes in relation to player movement (as it should) when you view it in the properties tab. The problem is, the Enemy model doesnt turn towards the player regardless of this.

So I’m guessing the npcs are owned by the server,

  1. move all logic to the server, good for multiplayer games
  2. set the ownership of the NPCs to the player
    npcHumanoidRootPart:SetNetworkOwner(playerBeingAttacked)

You could also use CFrame, but in my opinion, physics is better in this case

Yes moving the logic to the server is good for multiplayer games but when youre dealing with 50-100 NPCs in a single game the server load can be quite high. Thats why the AlignOrientation logic (which is very taxing for the server to do) is being done on the Client.

Ive tried setting the networkOwnership of the NPCs awhile back. Guess il try it again though maybe i missed something somewhere.

Use a runservice renderstepped event to set the hrt cframe to the same position but different orientation, smth like

Hrt.CFrame = CFrame.new([HRT pos vector],[player pos vector for lookat, but maybe remove the Y height])

Mhm yes ive done that on my very first iteration. The problem with that however is that it makes their movement very very choppy

Tried using lerp? CharacterLimit

How exactly would i use lerp in this case though? CFrame in general stops the NPC in its tracks as it overrides the pathfinding which causes the choppyness

Well if you use pathfinding on the server and lerp on the client that should be fine, that actually makes me wonder what do you even use for the pathfinding?

If you used something like this function from my post, and lerp on the client for orientation that should work.

Lerp example:
HRT.CFrame = HRT.CFrame:lerp(goal, 0.1)

Pathfinding example:

If you want an NPC to turn towards the player, try implementing CFrame.lookAt().

Example:

AlignOrientation.CFrame = CFrame.lookAt(enemyHrp.Position, Vector3.new(plrHrp.CFrame.position.X, enemyHrp.CFrame.position.Y, plrHrp.CFrame.position.Z) * CFrames.Angles(0,angle,0)

Yeah this is what it looks like when i do that.

for reference im doing

		diff = v.HumanoidRootPart.Position - closestPlayer.Character.PrimaryPart.Position
		angle = math.atan2(diff.X, diff.Z)
		local goal = humanoidRootPart.CFrame*CFrame.Angles(0, angle, 0)
		humanoidRootPart.CFrame = humanoidRootPart.CFrame:lerp(goal, 0.1)

Try setting the lerp goal to just cframe.angles

This is what that looks like. Me thinks the NPCs are being teleported to 0,0,0 on the client somehow

Coming back to this, i dont understand how lerping might help in this case. Setting the CFrame in general would cause pathfinding to freeze in general so i dont understand how to use Lerping to fix this. Is there a specific property of Lerp that i have to use in this case? orrr

Usually if you do pathfinding on the server and lerping on the client there should be issues

Well yeahhh and it also seems setting CFrame in general. I’m trying to find a better way to orient the NPC without breaking the pathfinding now because AlignOrientation and movement constraints in general dont seem to work as intended.