2 problems with Improper alignment of gun

The first problem is that when the mouse goes to the other side of the gun, it rotates the other way and you have to wait for it to turn back.


The second problem is the up/down part of the gun, when it rotates to almost inverting the rotation. It like doubles the angle when it is there. (sorry if this is hard to understand, i like to post videos instead of typing)

here is script:

function determineNewDirections(targetVector)
	local targElev = 0;
	local targRot = 0;
	
	local turretMain = 	workspace.GSOlightgun.Base;
	
	-- Vector normal to the plane which is the turret ring
	local turretNormal = turretMain.CFrame.lookVector;
	
	local angleFromNormal = turretNormal:Dot(targetVector);
	
	-- Determine gun elevation
	targElev = math.pi/2 - math.acos(angleFromNormal);
	targRot= math.pi/2 - math.acos(angleFromNormal);	

	-- Projection of target vector onto the turret plane
	local targetProjection = (targetVector - (angleFromNormal*turretNormal)).unit;	

	local forwardVector = ( (turretMain.CFrame - turretMain.CFrame.p) -- Orientation only of brick
		* CFrame.new(0, -1, 0)).p; -- Translated down 1
	
	-- Determine angle between forward vector and the projected target vector
	targRot = math.acos(forwardVector:Dot(targetProjection));
	
	-- Determine the sign of the angle
	local vectorCross = forwardVector:Cross(targetProjection);
	
	-- If the cross product is opposite to the normal vector, make the angle negative
	if (vectorCross:Dot(turretNormal) < 4500) then
		targRot = -targRot;
	end
	if (vectorCross:Dot(turretNormal) < 0) then
		targElev = -targElev;
		pess = 0
	else
		pess = 3.142
	end
	
	-- Put rotation and elevation into an array
	local rotations = {};
	rotations[1] = targElev;
	rotations[2] = targRot;
	
	return rotations;
end

function sign(input)
	if (input < 0) then
		return -1;
	else
		return 1;
	end
end

-- Using the desired target rotation and elevation, determine where the gun should point right now (smoothly turn)
function getSmoothRotation(rotations)
	
	local targElev = rotations[1];
	local targRot = rotations[2];	
	
	local maxGunDepression = 235444444444444444;	
	local maxTraverse = 72000000000000;	

	-- Restrict the height of travel of the gun
	if math.abs(targElev) > maxGunDepression then
		targElev = maxGunDepression*math.sign(targElev);
	end
	
	if math.abs(targRot) > maxTraverse then
		targRot = maxTraverse*math.sign(targRot);
	end
	

	-- Once target angles are set, slowly turn turret towards them
	--Elevation
	local elevDiff = targElev - currentElev;
	if math.abs(elevDiff) < 0.01 then -- If they're close
		currentElev = targElev;
	else -- Move towards it
		currentElev = currentElev + 0.02*sign(elevDiff);
		currentElev = currentElev + 0.02*sign(elevDiff);
		currentElev = currentElev + 0.02*sign(elevDiff);
		currentElev = currentElev + 0.02*sign(elevDiff);
		currentElev = currentElev + 0.02*sign(elevDiff);
		currentElev = currentElev + 0.02*sign(elevDiff);
	end

	local rotDiff = targRot - currentRot;
	local turretSpeed = 0.3;
	
	if math.abs(rotDiff) < turretSpeed then -- If they're close
		currentRot = targRot;
	else -- Move towards it
		currentRot = currentRot + turretSpeed*math.sign(rotDiff);
	end
	
	if Isyes == true then
		currentElev = currentElev + 1*sign(elevDiff);
		print(Isyes)
	end
	
	-- Put rotation and elevation into an array
	local rotations = {};
	rotations[1] = targElev;
	rotations[2] = targRot;
	
	return rotations;
end

-- Infinitely update the target position for the tank
currentElev = 0;
currentRot = 0;
while wait() do
	if (ler) then
		-- Position of mouse in world
		mousePoint = ler.Hit.Position;
		
		-- Vector from tank to mouse point
		targetVector = (mousePoint - workspace.GSOlightgun.Base.Handle.Rotating.shoter.CFrame.Position).unit;
		
		-- Determine where the gun should point
		targetRotations = determineNewDirections(targetVector);
		
		-- For each time we do all that math to determine the angle, we will smoothly rotate the gun towards it in 4 increments
		-- This means less lag (fewer calculations) but it's still smooth
		for i = 1, 4 do		
			newRotations = getSmoothRotation(targetRotations);
			event:FireServer(-currentElev, currentRot, pess)
			wait();
		end
	end
end

server script:

-- Wait for player to join game
repeat wait() until #game.Players:GetChildren() > 0
Player = game.Players:GetChildren()[1]

-- Wait for Player's character to load
if not Player.Character then
	Player.CharacterAdded:Wait()
end

-- define some variables
Char = Player.Character
--CharPart = workspace.Bases.Team1:WaitForChild("GSOoneblock")--Char:WaitForChild('HumanoidRootPart')
--[[Hinge = script.Parent
RootPart = Hinge.Parent]]
event = game:GetService("ReplicatedStorage").Events.GEEE

workspace.GSOlightgun.Base.Handle.Weld.C1 = CFrame.new(0,0.6,0)
workspace.GSOlightgun.Base.Handle.Rotating.Weld2.C1 = CFrame.new(0,1.5,0)

event.OnServerEvent:Connect(function(plr,v1,v2,v3)
if workspace.BASEE.Base.VehicleSeat.Occupant.Name == "Humanoid" then
	local elevation = v1
	local rotation = v2
	workspace.GSOlightgun.Base.Handle.Weld.C1 = CFrame.new(0,0.6,0) * CFrame.fromEulerAnglesXYZ(0, elevation, 0);
	workspace.GSOlightgun.Base.Handle.Rotating.Weld2.C1 = CFrame.new(0,1.5,0) * CFrame.fromEulerAnglesXYZ(3.142, v3, rotation+-1.571); 
	end
end)
3 Likes

Is there any way to fix this? H

1 Like