I have an arm that’s coming out of a wall, and I want it to keep looking at the player, if I just use CFrame.lookAt the arm will clip through the wall:
I’d like to limit it to an angle, basically give it a cone that it cannot exceed, i’ve tried clamping the angles but I never got a clean enough result. How can I achieve this?
If you imagine the cone it’s allowed to move in, the height of the cone is one axis and the base is the other two. If you take the distance of just the two base axes you get a radius inside the cone:
local coneDirection = Vector3.Z
local armDirection = ...
local height = armDirection:Dot(coneDirection)
local radialDir = (armDirection - coneDirection*height)
local radius = radialDir.Magnitude
A cone has a constant angle along its side, which is the same as having a constant ratio between base and height. Measure this ratio, clamp it to some max value, then convert it back into a direction:
local maxSlope = math.tan(1.326) --about 4
local slope = radius / height
if slope > maxSlope then
slope = maxSlope
end
local clampedDirection = radialDir * slope * height + coneDirection * height
is armDirection what CFrame.lookAt gave us? Or is it (player.Position - arm.Position).Unit, then i take the clamped direction and put it in the CFrame.lookAt?
local armDirection = (target.Position - pivotPosition).Unit
local height = armDirection:Dot(lookVector)
local radialDir = armDirection - lookVector * height
local radius = radialDir.Magnitude
local maxSlope = math.tan(1.326)
local slope = radius / height
if slope > maxSlope then slope = maxSlope end
local clampedDirection = radialDir * slope * height + lookVector * height
mesh.CFrame = CFrame.lookAt(pivotPosition, pivotPosition + clampedDirection) * offset
armDirection: the vector from the arm to the player
lookVector: the cone direction aka the wall normal
offset: it’s an offset to make the arm pivot around a pivot point i have
it has the same exact results as the clip i sent in post
In this case, I would use one of roblox’s mechanical constraints.
I think the BallSocketConstraint is best fit, and I would use it along with alignOrientation.
To initiate it the alignOrientation, go like this:
I am writing this as an alternative to azgjanna’s code. I don’t wish to interrupt azgjanna. Use azgjanna’s solution instead. this is just another method… …
Thanks for the suggestion but I have already considered using this, but it requires two attachements and I only have one pivot point (with some wittiness I can manifest the 2nd point), i’d also like the mathematical representation which is gonna be more flexible and i get to enhance my maths
Sorry, one more edit. I am trying to rotate cones in my head at 11pm:
local coneDir = Vector3.xAxis
local armDirection = rvec
--Clamp height to be positive to get a one-sided cone
local height = armDirection:Dot(coneDir)
local radialDir = armDirection - coneDir * height
local radius = radialDir.Magnitude
local maxSlope = 1/4
local slope = math.abs(radius / height)
if slope > maxSlope then
slope = maxSlope
end
local clampedDirection = radialDir.Unit * slope * height + coneDir * height
This makes the arm dissapear when its on the backwards cone, I could detect when to flip the cone using the dot product, but I dont know the cone angle in radians since you have it as 1/4