I cannot figure out how to get the opposite of what I have.
I want the turret to be able to rotate on the oppisite side of the platform: from 90 to -90 (yellow side), not from -90 to 90 (green side).
When I try changing the numbers I get the following error:
...invalid argument #3 to 'clamp' (max must be greater than or equal to min)
I tried using 90 and 270 but that doesn’t work. It will only rotate from 90 to 180 (yellow side) then jump back to 90.
Here is the script if anyone can help me understand what’s going wrong:
seat:GetPropertyChangedSignal("Occupant"):Connect(function()
if seat.Occupant then
occupied = true
while task.wait() do
if occupied then
-- find player and mouse postion
local character = seat.Occupant.Parent
local player = game.Players:WaitForChild(character.Name)
local MouseLock = character:WaitForChild("RF_MouseLock")
local MouseHitPosition = MouseLock:InvokeClient(player)
-- rotate toward mouse
if (MouseHitPosition-housing.Position).magnitude > 12 then
local rotationCFrame = CFrame.new(housing.Position, MouseHitPosition)
local x, y, z = rotationCFrame:ToOrientation()
local newYAngle = math.clamp(y, math.rad(-90), math.rad(90)) --limit right/left
local newXAngle = math.clamp(x, math.rad(-45), math.rad(45)) --limit down/up
local newRotationCFrame = CFrame.fromOrientation(newXAngle, newYAngle, z)
housing.CFrame = newRotationCFrame + housing.Position
end
end
end
else
occupied = false
return
end
end)
This means that the minimum value you set was bigger than the maximum value (so like min of 90, max of -90) which makes no sense and thus errors
You can try setting the min to 90 and the max to 270, however, orientation can be negative so that could mess it up. You can either add 360 to it if it’s negative, or you can get the angle with math.atan2, which uses some trigonometry.
Extremely sorry for the delay, I got caught up in a few things and completely forgot about this post until I laid in bed and randomly remembered. This should do what you want it to do.
local function clamp(a: number)
local b = nil;
b = math.abs(a)
b = math.clamp(b, math.rad(90), math.rad(180))
return a < 0 and -b or b
end
All your calculations are in world space though, so if you want these turrets to be able to face anywhere in game, you’ll need to add in a world to local space transform too. As-is, you can’t just rotate your model to change which way the installment faces.
If this is going to be used in a live game, I’d also strongly urge you not to do it this way. Adjusting CFrames on the server makes everything look stuttery on all clients. It won’t move smoothly with the camera of the person in the seat either. And polling the client for mouse position with a RemoteFunction?! That means the person in the seat will have their full round trip ping as input latency, or if you CFrame things locally too, server and client will be competing to set the part orientations (more stuttering). There’s no need to do any of this if you just use hinges, the position changes will replicate automatically because the player in the Seat will have network ownership of the turret. Hinges also let you set the angle limits, rotation speeds, etc. without having to build CFrames, you just set the angle and angle limits in degrees.
No problem. I second what Emily said though. I tested the time between the initial movement of the mouse and the movement of the turret and saw upwards of ~220ms at times. When you have that much of a delay, your players will not only have to account for any bullet velocity you set up, but the input delay as well - which isn’t optimal. Obviously feel free to do what your heart desires, but if it’s going to be used in a game I highly recommend moving over to physics or a more optimized system. If you move over to physics and keep network ownership on the client I’d run a few checks on the server though, as clients could very easily give themselves full (including unwanted) control of the turret’s position and rotation.
I tried using hinges but could not figure out how to get a hinge to move to a mouse position.
I have another turret for a tank that uses hinges and it works great, but it moves with keys not the mouse position. I want quick easy movements and the keyboard doesn’t offer that.
I don’t understand why you think this is a bad idea.
What is the difference between the way I am doing it and having the Client send their mouse position through a Remote Event. It’s the same ammount of information either way.
There are some issues unique to RemoteFunctions that call a client from a server, especially if it’s done rapidly, like every frame. Unlike RemoteEvents, they yield waiting for a response. This can be a problem if the client doesn’t respond, a reason most devs avoid RemoteFunctions entirely. For something like user input, it just adds a ton of lag. RemoteFunctions are also slower than implementing the same system with RemoteEvents, even when used correctly.
No, because you don’t actually need to send any information from server to client. If someone’s in the seat, they can send their MousePosition to the server. You eliminate having to send an event from server to client every frame to request the mouse position, which is entirely unnecessary to do. The RemoveEvent solution uses no server to client bandwidth, the RemoteFunction solution uses a lot.