I want to make a 3 axis robot arm with a cool laser cannon which you can get to point the laser cannon directly at a vector3. this would be easy if the cannon was just on a stick and looked at stuff, but i decided it’d be cool to make a 3 axis robot arm instead.
I do not know how to do the math or calculations, I have made code that set the angles of the axis to whatever I want in degrees but thats about it.
I have tried to ask dev friends for help, chatgpt, nothing worked.
heres some details on the robot arm :
heres how each joint moves for clarity
heres my module script :
local module = {}
function module:CalculateJointCFrame(Joint:Instance, Angle:number)
local Position = Joint:GetAttribute("JointDefaultPosition") or Vector3.zero
local JointCFrame = CFrame.new(Position)
local RotationCFrame = CFrame.new()
local DefaultRotation = Joint:GetAttribute("JointDefaultRotation")
if DefaultRotation and typeof(DefaultRotation) == "Vector3" then
RotationCFrame*=CFrame.Angles(
math.rad(DefaultRotation.X),
math.rad(DefaultRotation.Y),
math.rad(DefaultRotation.Z)
)
end
local AxisUsed = Joint:GetAttribute("AxisUsed") or "X"
local RotationTable = {0,0,0}
local AxisDictionary = {x = 1, y = 2, z = 3}
local IndexToChange = AxisDictionary[string.lower(AxisUsed)] or 1
RotationTable[IndexToChange] = math.rad(Angle)
RotationCFrame*=CFrame.Angles(table.unpack(RotationTable))
JointCFrame*=RotationCFrame
return JointCFrame
end
function module:PointCannonAt(LookPos:Vector3)
local Cannon = script.Parent
if not Cannon:IsA("Model") then return end
local Arm = Cannon:FindFirstChild("Arm")
if not Arm or not Arm:IsA("Model") then return end
local Joints = {
Joint1 = Arm:FindFirstChild("Joint1"),
Joint2 = Arm:FindFirstChild("Joint2"),
Joint3 = Arm:FindFirstChild("Joint3")
}
for _, joint in Joints do if not joint or typeof(joint) ~= "Instance" or not joint:IsA("BasePart") then return end end
local Cannon = Arm:FindFirstChild("Cannon")
if not Cannon or not Cannon:IsA("Model") then return end
local MainCannonPart = Cannon:FindFirstChild("CannonShell") or Cannon:FindFirstChild("CannonFrame") or Cannon.PrimaryPart
if not MainCannonPart or not MainCannonPart:IsA("BasePart") then return end
local ImportantPositions = {
Joint1Pos = Joints.Joint1.Position,
Joint2Pos = Joints.Joint2.Position,
Joint3Pos = Joints.Joint3.Position,
CannonPos = MainCannonPart.Position
}
-- how do i calculatey the angles for each motor?
local XRotation = 0
local YRotation = 0
local ZRotation = 0
local Motors = Arm.Joints
local Motor1 = Motors.Joint1
local Motor2 = Motors.Joint2
local Motor3 = Motors.Joint3
Motor1.C1 = module:CalculateJointCFrame(Motor1, XRotation)
Motor2.C1 = module:CalculateJointCFrame(Motor2, ZRotation)
Motor3.C1 = module:CalculateJointCFrame(Motor3, YRotation)
end
return module
heres a simplified version of the cannon model with the scripts to help even more
SimplifiedCannon.rbxm (49.8 KB)
it’d be great if you could figure out the math


