Hello there, I am having an issue with my tank control system. My goal is to make the tank point at a certain point (the player’s mouse position in 3D). The way I am initially doing this is simple: Call CFrame.lookAt() with the turret’s position and the point’s position, I convert it to orientation values using the CFrame:ToOrientation() function, and then I simply set the turret angle of the tank equal to the Y angle returned by the ToOrientation function and set the barrel angle of the tank equal to the X angle returned by the ToOrientation function. So something like this:
local x, y = CFrame.lookAt(turret_position, targeted_mouse_position):ToOrientation()
barrel_angle = x
turret_angle = y
And it works fine, but only on a flat surface (red circle is where barrel is pointing at, white circle is where it should point at):
However, on a 45° slope for example, it does not produce accurate results:
What can I do to make it point to the correct location? I have tried various methods such as converting the mouse position to the tank’s local space but it did not really work. Do I need more advanced math for this?
--ServoTools
local assert, atan2, deg, V0 = assert, math.atan2, math.deg, Vector3.zero
local function isNan(n: number): boolean
return n ~= n
end
local function pointServoTo(servo: HingeConstraint, point: Vector3, pointer: Attachment?)
assert(servo.Attachment0)
assert(servo.Attachment1)
local servoBaseAtt = servo.Attachment0
local servoPointerAtt = servo.Attachment1
local servoBaseCF = servoBaseAtt.WorldCFrame
local pointOffset = pointer and servoBaseAtt.WorldPosition - pointer.WorldPosition or V0
local pointRelativeToBase = servoBaseCF:PointToObjectSpace(pointOffset + point)
local angleRelativeToBase = atan2(pointRelativeToBase.Y, -pointRelativeToBase.Z)
local a = angleRelativeToBase
servo.TargetAngle = isNan(a) and servo.TargetAngle or deg(a)
end
return {
pointServoTo = pointServoTo,
}
How to use it:
local ServoTools = require(game.ReplicatedStorage.ServoTools)
local Turret = script.Parent
local Servo1 = Turret.Servo1
local Servo2 = Turret.Servo2
local MuzzleAtt = Turret:FindFirstChild("MuzzlePoint", true)
local Target = game.Workspace.Target
while wait() do
ServoTools.pointServoTo(Servo1, Target.Position, MuzzleAtt)
ServoTools.pointServoTo(Servo2, Target.Position, MuzzleAtt)
end
Well @ThanksRoBama’s idea is probably the solution as it creates the mouse position to the tank’s space, which would be a way on how to solve it because of the difference it is during a leveled ground and on a slope.
Thank you very much! I dont use HingeConstraints (I calculate the CFrames manually), so I didnt use most of the code you had written but the math inside the function really helped me.