Help In adding A Gun Stabilization

Hello!, I am trying to add a both Turret and Gun Stabilization to my Tank System like seen in Modern Tanks. however i am struggling. Any Help or Advices will be greatly appreciated!

I tried by finding the Dot Product between the WorldUpvector and the Tanks Upvector (which i try to not take account in the tanks tilt as it fails there) and the Dot product of the Tanks Lookvector to the Upvector to take in account for the Pitch of the tank. It works however when i rotate the Tank by 90 Degrees and tilt it, it seems to follow. and even if its the direction where it works perfectly, if i tilt it enough it reverses direction. and at this point i ran out of options…


The red highlight shows the tanks Upvector Modified

Here is my Current Code:

local tank = script.Parent
local Main = tank:WaitForChild("Main")

local offset = 15
local WorldVector = Vector3.new(0,1,0)

game:GetService("RunService").Heartbeat:Connect(function()
	local UpVector = Main.CFrame.UpVector
	local lookvector = Main.CFrame.LookVector
	local actualvector = Vector3.new(0, UpVector.Y,UpVector.Z).Unit
	
	local dotproduct = actualvector:Dot(WorldVector)
	local pitchproduct = lookvector:Dot(WorldVector)
	
	local pitch = math.deg(math.acos(pitchproduct))
	local sign = 1
	if pitch <= 90 then
		sign = 1
	else
		sign = -1
	end
	
	local angle = math.deg(math.acos(dotproduct)) * sign
	local  gx, gy, gz = tank.Motors.Gun.C0:ToEulerAnglesXYZ()
	local totaladdedangle = (gx + offset) - angle
	tank.Motors.Gun.C0 = CFrame.new(0,0,0) * CFrame.Angles(math.rad(totaladdedangle), 0, 0)
end)

nvm, i fixed it by just only using the tanks Lookvector instead.

local tank = script.Parent
local Main = tank:WaitForChild("Main")

local offset = 5
local WorldVector = Vector3.new(0,1,0)

function lerp(start, goal, alpha)
	return start + (goal - start) * alpha
end

game:GetService("RunService").Heartbeat:Connect(function(dt)
	local lookvector = Main.CFrame.LookVector
	local dotproduct = lookvector:Dot(WorldVector)
	local angle = math.deg(math.acos(dotproduct))
	
	local a = 1
	if angle <= 90 then
		a = -1
	else
		a = -1
	end
	angle = (angle - 90) * a

	local  gx, gy, gz = tank.Motors.Gun.C0:ToEulerAnglesXYZ()
	local totaladdedangle = (gx + offset) - angle
	totaladdedangle = math.clamp(totaladdedangle, -15, 15)
	tank.Motors.Gun.C0 = CFrame.new(0,0,0) * CFrame.Angles(math.rad(totaladdedangle), 0, 0)
end)
1 Like