So I have a turret and when the player clicks, it takes the players camera rotational cframe and applies it to the turret so the turret faces in the direction of the players camera. However the issue i have is i want it so if the players camera is facing upwards and they click, i dont want the turret to point directly upwards just face in the direction of the camera and not rotated in an upwards direction.
I have no idea how I would clamp this. I could get the lookvector of the camera, clamp the upwards vector, but then i dont know how to make a lookvector back to a rotational cframe to apply to the turret. Any ideas?
local Part = Instance.new("Part")
Part.Anchored = true
Part.CanCollide = false
Part.Parent = workspace
while task.wait() do
local ClampedYAxis = math.clamp(Part.Orientation.Y,-45,45)
Part.Orientation = Vector3.new(Part.Orientation.X,ClampedYAxis,Part.Orientation.Z)
So In my OP I said that I get the rotational vector of the camera (by doing camera.CFrame - camera.CFrame.Position) and I want to clamp it so that it can’t point directly up only side to side. Then apply this CFrame to the turret.
I encountered this problem when making my turret system and ended up coming up with a hacky yet effective solution using a dummy attachment.
One way to get the “Orientation” of the camera is to create a dummy attachment, and then give it the same CFrame as the camera using the following code:
local dummyattachment = Your.Attachment.Here
local camera = workspace.CurrentCamera
-- align our attachment with the camera
dummyattachment.WorldCFrame = camera.CFrame
-- now that our attachment's orientation matches the camera's, lets apply the constraint to the dummy attachment and then set the camera's orientation to match the attachment's!
local constrainedY = math.clamp(dummyattachment.WorldOrientation.Y, -45, 45) -- apply constraint
dummyattachment.WorldOrientation = Vector3.new(dummyattachment.WorldOrientation.X, constrainedY, dummyattachment.WorldOrientation.Z)
-- now lets cframe the camera to match our newly constrained dummy attachment
camera.CFrame = dummyattachment.WorldCFrame
Now it’s important to note that even though in the code example I only constrained the Y axis, these constraints can be applied to any axis you want. It’s also important to use WorldCFrame and WorldOrientation, because an attachment’s CFrame and Orientation only reflect their offset from the part they are parented to.
You could alternatively use camera.CFrame:ToOrientation(), which will return an orientation X, Y, and Z variable for you to work with.
Thank you so much! Using an attachment and editing its orientation property’s, Genius! But with the ToOrientation method, I have to apply the rotation to a weld which used cframe. So is there a way to turn a cframe to a orientation, then back to a cframe?
Edit: (off topic from cframes) how did you make the turret server to client? Did you send all information from local script to server to apply orientation changes to server? Or simply set the network owner of the turret to the player?
Yep! You can use CFrame.fromOrientation() like @dthecoolest said in their reply.
I ended coming up with a physics-based solution for my turret using more or less the following method:
all moving parts on the turret and unanchored and connected to each other using weldConstraints
this group of moving parts is moved around a pivot point using a BallSocketConstraint (with rigidity enabled, and all limits set to zero. I made the system before RigidConstraints came out, so I would go with those for new projects. The purpose of the constraint is to align the cframe of two attachments (one connected to the base of the turret, and one connect to the anchor of the moving parts. I chose to use attachments instead of anchoring the turret and using remove events because I found that physics replicated automatically when I set the turret’s NetworkOwnership to the player, and much more smoothly/naturally too, due to the way physics are interpolated.
This method requires no remote events, only the moving of an attachment. The server really only handles setting up networkOwnership and adding Controller scripts to the character.