Having Trouble Rotating Cannon Barrel

So I have this Cannon and it has a base and a barrel. The base rotates based on where the mouse is pointing (excluding the Mouse.Hit.Y axis), this works fine.
However, I want the barrel to rotate (clamped at -45, and 45 degrees) based on where the mouse is pointing but only ‘up’ and ‘down’, so it cannot rotate side-to-side, this works fine as well.

My issue is that the barrel stays static in the other axis’ but I cannot figure out how I need to rotate it in order to be relative to the entire rotation of the cannon model- or ‘base’. The issue is pretty obvious in this gif…

Edit: The code below is flawed, see comments below.

Here’s the code:

local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

local LocalPlayer = Players.LocalPlayer
local Mouse = LocalPlayer:GetMouse()
local Model = workspace:WaitForChild("Cannon")
local PivotPart = Model:WaitForChild("PivotPart")

local AngleMax, AngleMin = 45, -45

local function SimulateRotation()
	Model:PivotTo(Model:GetPivot() * CFrame.Angles(0, math.rad(.1), 0))
end

local function UpdatePartRotation()
	local MousePosition = Mouse.Hit.Position
	local PartPosition = PivotPart.Position
	local LookVector = (MousePosition - PartPosition).Unit

	local Angle = math.rad(math.clamp(math.deg(math.asin(-LookVector.Y)), AngleMin, AngleMax))
	
	PivotPart.CFrame = CFrame.new(PartPosition) * CFrame.Angles(0, 0, -Angle) * CFrame.Angles(0, math.rad(-90), 0)
end

while true do
	RunService.RenderStepped:Wait()

	SimulateRotation()
	UpdatePartRotation()
end

I should note that advanced CFraming is something I’m particularly unfamiliar with. So something that’s explained would help me learn.

Cheers!

1 Like

from what I can see it looks like it is rotating with the bottom part of the model but your barrel is not oriented in the right way, Maybe try messing around with the axis your actually updating. Hope this helps

1 Like

After some testing out different methods this is what best represented what I wanted to do.
However the only issue remains is that I do not know how to clamp the ‘up/down angle’ so the cannon barrel cannot rotate too far upwards or downwards.

local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

local LocalPlayer = Players.LocalPlayer
local Mouse = LocalPlayer:GetMouse()
local Model = workspace:WaitForChild("Cannon")
local PivotPart = Model:WaitForChild("PivotPart")
local Camera = workspace.CurrentCamera

local r = math.rad
local c = math.clamp
local AngleMax, AngleMin = r(45), r(-45)

local function SimulateRotation()
	Model:PivotTo(Model:GetPivot() * CFrame.Angles(0, r(.1), 0))
end

local function UpdatePartRotation()
	local MouseHitPos = Mouse.Hit.Position
	local PivotPartPos = PivotPart.Position
	local PivotPartCF = PivotPart.CFrame
	local LookAt = CFrame.lookAt(PivotPartPos,MouseHitPos)
	local CF = CFrame.fromMatrix(PivotPartPos, PivotPartCF.XVector, LookAt.YVector, PivotPartCF.ZVector)
	
	PivotPart.CFrame = CF
end

while true do
	RunService.RenderStepped:Wait()

	SimulateRotation()
	UpdatePartRotation()
end

To be clear, this behavior of where it can rotate to high/low is what I do not want. I want it clamped between -45, and 45 degrees.

1 Like

HI again, To clamp the angle Just use math.clamp(Number,Min,Max)

1 Like

I figured it out!

local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

local LocalPlayer = Players.LocalPlayer
local Mouse = LocalPlayer:GetMouse()
local Model = workspace:WaitForChild("Cannon")
local PivotPart = Model:WaitForChild("PivotPart")
local Camera = workspace.CurrentCamera

local r = math.rad
local c = math.clamp
local AngleMax, AngleMin = r(45), r(-45)

local function SimulateRotation()
	Model:PivotTo(Model:GetPivot() * CFrame.Angles(0, r(.1), 0))
end

local function GetMagnitude(A: Vector3, B: Vector3): number
	return (A-B).Magnitude
end

local function IsBehind(A: CFrame, B: CFrame): boolean
	return GetMagnitude((A*CFrame.new(0,0,-1)).Position,B.Position) > GetMagnitude(A.Position,B.Position)
end

local function UpdatePartRotation()
	local PivotPartCF = PivotPart.CFrame
	local LookAt = CFrame.lookAt(PivotPartCF.Position, Mouse.Hit.Position)
	local CF = CFrame.fromMatrix(PivotPartCF.Position, PivotPartCF.XVector, LookAt.YVector, PivotPartCF.ZVector)
	local X, Y, Z = LookAt:ToOrientation()
	
	X = c(IsBehind(PivotPartCF, Mouse.Hit) and -X or X, AngleMin, AngleMax) --// Limit up/down angle
	
	LookAt = CFrame.fromOrientation(X, Y, Z)
	
	CF = CFrame.fromMatrix(PivotPartCF.Position, PivotPartCF.XVector, LookAt.YVector, PivotPartCF.ZVector)

	PivotPart.CFrame = CF
end

while true do
	RunService.RenderStepped:Wait()

	SimulateRotation()
	UpdatePartRotation()
end

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.