Need Help With Turret Rotation

Hello there, I am trying to make a turret rotation system similar to a tank or an anti air piece into my games that uses W A S D keys for the movement.

I’m stuck fairly into the beginning, I’m not sure how to approach the best way of rotating the system itself, I want to first be able to just rotate one piece and I’ve been trying the barrel but I think I’m sending way to many remote events and I feel like multiple are being ignored.

So simply put it, what is one of the BETTER ways to rotate a part from user input?

Here is currently my scripts:

Client side:

UIS.InputBegan:Connect(function(input)
	if (is_gunner) then
		local contrl_db = true
		
		while UIS:IsKeyDown(RIGHT_TRAVERSE) do
			game.ReplicatedStorage.GunControls:FireServer(RIGHT_TRAVERSE)
			task.wait(0.1)
		end
	end
end)

Server Side:

local RIGHT_TRAVERSE = Enum.KeyCode.D

game.ReplicatedStorage.GunControls.OnServerEvent:Connect(function(plr, control)
	if (control == RIGHT_TRAVERSE) then
		
		rotation = CFrame.Angles(0, math.rad(0.5), 0)
		
		script.Parent.Canon.CFrame = script.Parent.Canon:GetPivot()
		script.Parent.Canon:PivotTo(script.Parent.Canon.CFrame * rotation)
	end
end)

I think I’m sending way to many remote events and I feel like multiple are being ignored.

You’re most likely sending way too many remote events and exhausting the event invocation queue. In other words, the server can’t keep up with the amount of events being fired from each client, which is a likely situation given your current structure for your turret system.

First, you shouldn’t want to constantly fire the RemoteEvent to move the turret. Depending on how many turrets you have, and how many players can move those turrets, it can be enough to worsen latency for all players if the server has to process an absurd amount of remote events given (or ignore them, as you’ve already described).

Ideally, you’ll want to only fire an event where needed to let the server know when to begin moving or when to end moving the turret. It can look like this on the client:

local RIGHT_TRAVERSE = Enum.KeyCode.D

UIS.InputBegan:Connect(function(input)
	if (is_gunner) and input.KeyCode == RIGHT_TRAVERSE then
		local contrl_db = true -- not sure what this is used for
		game.ReplicatedStorage.GunControls:FireServer(RIGHT_TRAVERSE, "StartMoving")
	end
end)

UIS.InputEnded:Connect(function(input)
	if (is_gunner) and input.KeyCode == RIGHT_TRAVERSE then
		local contrl_db = true -- not sure what this is used for
		game.ReplicatedStorage.GunControls:FireServer(RIGHT_TRAVERSE, "StopMoving")
	end
end)

You might be noticing why we’re passing in an additional parameter - that’s to let the server know how the turret should respond with the information passed in by the client. You would shift your rotation mechanism entirely on the server after that:

local RIGHT_TRAVERSE = Enum.KeyCode.D
local isMoving = false

game.ReplicatedStorage.GunControls.OnServerEvent:Connect(function(plr, control, moveAction)
	if (control == RIGHT_TRAVERSE) then
		if moveAction == "StartMoving" and not isMoving then
			isMoving = true
			
			while isMoving do
				rotation = CFrame.Angles(0, math.rad(0.5), 0)

				script.Parent.Canon.CFrame = script.Parent.Canon:GetPivot()
				script.Parent.Canon:PivotTo(script.Parent.Canon.CFrame * rotation)
				
				task.wait(0.1)
			end
		elseif moveAction == "StopMoving" and isMoving then
			isMoving = false
		end
	end
end)

Of course, this isn’t the most ideal way to implement this - this is just a rough structure of what it could look like. Depending on how many turrets you have, you’ll probably want to use a dictionary or capture something onto the object itself instead of using a singular variable to control rotation, and implement sanity checks to ensure that cheaters shouldn’t be able to move turrets if they are unable to according to your game logic.

Hope this helps :slight_smile:

2 Likes

Thanks so much! I knew something was way off on this, 2 Quick questions by the way;

1: I want to be able to be able to elevate/depress (Y-Axis) my gun and traverse it (X-Axis) at the same time, would this just need another input similar to the one you made, or is there some other route I should go?

2: What benefits would a Dictionary provide for multiple turrets? I’m trying to make a game where there might be up to say 8 or 10 of these systems firing at once so I want to know the best ways to optimize since I want to be performance friendly.

1 Like
  1. The way I would approach this is by using an input to keep track of which direction the turret should move in on the client - you could make it as simple as using a string or enum that specifies the direction, like TopLeft, Top, BottomRight, etc, or use a vector that represents that direction value. Then, I would fire an event to the server that updates the direction, while also using an attribute on the turret that keeps track of the last updated direction. In the loop, I would continuously reference the attribute so that there wouldn’t be a need to cancel and then create a new loop each time.

  2. The dictionary is just one method of preventing multiple loops being created for one turret, when ideally you’ll only want to have one loop be active at a time per turret. There are many different ways of implementing this, while I usually use dictionaries in my experiences, using attributes are also acceptable and straight-forward for your use-cases. Anything goes, really.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.