Changing NPC animation playing on Server Script to Local script

I currently have this script that allows an NPC to move towards a player and play an animation based on how far it is from the player.

The problem however is the the animations are played on a server script which i found out much worse the having it on a local script and it perevtns me from using animation events which i badly need.

Basically to know what would be a good way of converting the animation part of this script to a new local script and keep movement on the Server script. Thanks.

I’ve also tried sending the Data from my FindNearestPlayer via a Remote event to a local script where it would use the code at the bottom of the script to play animations but it would over load the remote event limit causing the script not to work.

local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

local Model = script.Parent.Parent
local humanoid = script.Parent
local root = humanoid.Parent.PrimaryPart
root:SetNetworkOwner(nil)

local TargetDistance = script.Parent.Parent:GetAttribute("TargetDistance")
local StopDistance = script.Parent.Parent:GetAttribute("StopDistance")
local Damage = script.Parent.Parent:GetAttribute("Damage")
local AttackDistance = script.Parent.Parent:GetAttribute("AttackDistance")
local AttackCooldown = script.Parent.Parent:GetAttribute("AttackCooldown")

local LastAttack = tick()

local Animator = humanoid:WaitForChild("Animator")
local IdleAnimation = script:WaitForChild("Idle")
local WalkingAnimation = script:WaitForChild("Walk")
local AttackAnimation = script:WaitForChild("Attack")

local IdleTrack = Animator:LoadAnimation(IdleAnimation)
local WalkingTrack = Animator:LoadAnimation(WalkingAnimation)
local AttackTrack = Animator:LoadAnimation(AttackAnimation)

local AttackWarning = false






if WalkingTrack.IsPlaying or AttackTrack.IsPlaying then
	IdleTrack:Stop()
else
	IdleTrack:Play()
end



function FindNearestPlayer()
	local playerList = Players:GetPlayers()
	
	local nearestPlayer = nil
	local distance = nil
	local direction = nil
	
	for _, player in pairs(playerList) do
		local character = player.Character
		local distanceVector = (player.Character.HumanoidRootPart.Position - root.Position)
		if character then	
			if not nearestPlayer then 
				nearestPlayer = player
				distance = distanceVector.Magnitude
				direction = distanceVector.Unit

			elseif distanceVector.Magnitude < distance then
				nearestPlayer = player
				distance = distanceVector.Magnitude
				direction = distanceVector.Unit
			end
		end
	end
	return nearestPlayer, distance, direction
	
end
	

RunService.Heartbeat:Connect(function() 
	local nearestPlayer, distance, direction = FindNearestPlayer()
	
	if nearestPlayer then

		if distance <= TargetDistance and distance >= StopDistance then
			--Runs when walking
			if not WalkingTrack.IsPlaying then
				WalkingTrack:Play()
			end
			humanoid:Move(direction)
		else
			--Runs when standing still
			if WalkingTrack.IsPlaying then
				WalkingTrack:Stop()
			end
			humanoid:Move(Vector3.new())
		end
		
		if distance <= AttackDistance and tick() - LastAttack >= AttackCooldown and Model:GetAttribute("Stunned") == false then
			--runs when attacking
			
			AttackTrack:Play()
			LastAttack = tick()
			
		end
	end 
end)

-- what the walkspeed and jump height will revert to
local BaseWalkSpeed = 12
local BaseJumpHeight = 50

coroutine.resume(coroutine.create(function()
	while true do
		wait()
		if script.Parent.Parent:GetAttribute("Stunned") == true then
			script.Parent.Parent:FindFirstChild("Humanoid").WalkSpeed = 0
			script.Parent.Parent:FindFirstChild("Humanoid").JumpHeight = 0
		else
			script.Parent.Parent:FindFirstChild("Humanoid").WalkSpeed = BaseWalkSpeed
			script.Parent.Parent:FindFirstChild("Humanoid").JumpHeight = BaseJumpHeight
		end
	end
end))