Handling Tower Defense Enemies on the Server

Hello, I’m working on a Tower Defense Game, and I’m unsure of which method to use to change the Orientation of an Enemy on the server. I’m currently using the lookVector to make the enemy move in the direction it is pointing every frame, but I’m not sure what would be the way to Create a smooth turn that would change by a certain amount every frame when the enemy position is close enough to a node. Note that I know its bad to change the positions of anything on the server every frame. This question is only for changing the position and orientation of the enemy on the server.

How would I change the orientation smoothly depending on the speed but not in one single Frame?

Move Function that fires every Heartbeat:

local function Move(Enemy: EnemyType, DeltaTime: number)
	local self = Enemy;
	
	local Primary = Enemy.Object.PrimaryPart
	
	if not Primary then
		return;
	end
	
	local Speed = self.Speed;
	local CurrentPoint = self.CurrentPoint;
	
	local NextPoint = WayPoints[CurrentPoint]
	
	local LookVector = Primary.CFrame.LookVector;
	local PrimaryPosition: Vector3 = Vector3.new(Primary.Position.X, 0, Primary.Position.Z);
	local WaypointPosition: Vector3 = Vector3.new(NextPoint.Position.X, 0, NextPoint.Position.Z);
	
	local Distance: Vector3 = (PrimaryPosition - WaypointPosition) :: Vector3;
	
	
	Primary.CFrame += LookVector * Speed*DeltaTime;
	
	if Distance.Magnitude < 1 then
		local PointAfter = WayPoints[CurrentPoint+1];
		local TurnLength = 90/Speed*DeltaTime;
		
		--local TurnDirection = ???
	
	end
end

The Heartbeat Connection:

RunService.Heartbeat:Connect(function(DeltaTime)
	for _, _Enemy in ipairs(Enemies) do
		local self = _Enemy;
		local CurrentWayPoint = WayPoints[self.CurrentPoint];
		
		if not self.Object.PrimaryPart then
			return;
		end
		
		local Primary = self.Object.PrimaryPart;
		local Speed = self.Speed;
		
		local YCordinate = CurrentWayPoint.Position.Y+(self.Object:GetExtentsSize().Y/2)
		local PrimaryPosition: Vector3 = Vector3.new(Primary.Position.X, YCordinate, Primary.Position.Z)
		
		local WayPointPosition: Vector3 = Vector3.new(CurrentWayPoint.Position.X, YCordinate, CurrentWayPoint.Position.Z) 
		
		local Distance = PrimaryPosition-WayPointPosition;
		local Unit = Distance.Unit;
		local Magntiude = Distance.Magnitude;
		
		local Ratio: number = Magntiude/Speed
		
		Move(self, DeltaTime)
	end
end)

Use an align orientation instead. Also instead of changing the orientation by the look vector use CFrame.lookAt(origin, targetPos) .

I was thinking about using that, but while in testing that doesn’t create the transition effect but instead just does it all in one frame. What I intend for the enemies to do is slowly turn to that lookat CFrame over a few frames.

Did you try lowering the max torque?

How would I use align orientation though? There needs to be 2 attachments for align orientation. I do not know where they would go.

Thanks for the feedback though. Your solution was brilliant.

I’ve tested it and it seems that because the Root PrimaryPart of the rig is anchored, the AlignOrientation Constraint does not apply.

You actually don’t need two attachments. You can use 1, but then set the target cframe. There’s a setting and then set it to one attachment.

Edit: oh I misread it. So instead maybe you can tween or lerp the cframe instead.

However, I doubt you actually need collisions, right? So maybe you don’t even need the tower anchored, but instead change the collision group.

How would I tween and lerp is though? I need it to be a transition, which alignOrientation certainly does. However, that property needs the root to not be anchored to function, which I don’t want. What the intended behavior should be is alignOrientation-like actions while the rootPart is Anchored.

Try something like this:

local goal = CFrame.lookAt(rootPart.Position, targetPos)
TweenService:Create(rootPart, tweenInfo, {CFrame = goal}):Play()

However, do you really need the tower to be anchored? If you don’t want collisions you don’t even need the tower to be anchoed.

How would that be incorperated into RunService though? The orientation tween should be quite fast because its just a turn.

I actually don’t think this would be case. I’ve made a weighted camera before and it’s basically the same principle. Try it out. Also can you disable collisions? Unanchoring would probably be the easiest solution.