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.
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
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.
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