How to rotate a tank turret and gun?

Hi all. I am trying to build a first person tank game. As you can see in the attached video, I have used a smooth look at action to get the turret and gun to follow where I point my mouse, however, I cannot figure out how to constrain the gun to the vertical axis. Right now it just follows anywhere. I just want the gun to move up and down to where I point the camera. Help?

In the LateUpdate() callback, set the localRotation of the gun like this.

public class ClampRotation : MonoBehaviour
{
    public GameObject gun;

    void LateUpdate()
    {
        // if you want to clamp on X-Axis
        gun.transform.localEulerAngles = new Vector3( gun.transform.localEulerAngles.x, 0, 0 );
    }
}

EDIT: If you want to clamp the the degrees then you can add two extra fields

[SerializeField] private float minAngle, maxAngle;

public class ClampRotation : MonoBehaviour
{
    public GameObject gun;

    void LateUpdate()
    {
        float clampedAngle = Mathf.Clamp( gun.transform.localEulerAngles.x, minAngle, maxAngle );
        // if you want to clamp on X-Axis
        gun.transform.localEulerAngles = new Vector3( clampedAngle , 0, 0 );
    }
}

@ConcanoPayno thanks, but I’ve run into a problem. I keep getting this error that the name “gun” does not exist in the current context. Here is the source code for the gun

using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
	[ActionCategory(ActionCategory.Transform)]
	[Tooltip("Smoothly Rotates a Game Object so its forward vector points at a Target. The target can be defined as a Game Object or a world Position. If you specify both, then the position will be used as a local offset from the object's position.")]
	public class SmoothLookAt : FsmStateAction
	{
		[RequiredField]
		[Tooltip("The GameObject to rotate to face a target.")]
		public FsmOwnerDefault gameObject;
		
		[Tooltip("A target GameObject.")]
		public FsmGameObject targetObject;
		
		[Tooltip("A target position. If a Target Object is defined, this is used as a local offset.")]
		public FsmVector3 targetPosition;

		[Tooltip("Used to keep the game object generally upright. If left undefined the world y axis is used.")]
		public FsmVector3 upVector;
		
		[Tooltip("Force the game object to remain vertical. Useful for characters.")]
		public FsmBool keepVertical;
		
		[HasFloatSlider(0.5f,15)]
		[Tooltip("How fast the look at moves.")]
		public FsmFloat speed;
		
		[Tooltip("Draw a line in the Scene View to the look at position.")]
		public FsmBool debug;

		[Tooltip("If the angle to the target is less than this, send the Finish Event below. Measured in degrees.")]
		public FsmFloat finishTolerance;

		[Tooltip("Event to send if the angle to target is less than the Finish Tolerance.")]
		public FsmEvent finishEvent;

		private GameObject previousGo; // track game object so we can re-initialize when it changes.
		private Quaternion lastRotation;
		private Quaternion desiredRotation;

        public override void Reset()
		{
			gameObject = null;
			targetObject = null;
			targetPosition = new FsmVector3 { UseVariable = true};
			upVector = new FsmVector3 { UseVariable = true};
			keepVertical = true;
			debug = false;
			speed = 5;
			finishTolerance = 1;
			finishEvent = null;
		}

        public override void OnPreprocess()
        {
            Fsm.HandleLateUpdate = true;
        }

		public override void OnEnter()
		{
			previousGo = null;
		}

        void LateUpdate()
        {
            //clamp on X-Axis
            gun.transform.localEulerAngles = new Vector3(gun.transform.localEulerAngles.x, 0, 0);
        }

        public override void OnLateUpdate()
		{
			DoSmoothLookAt();
        }

		void DoSmoothLookAt()
		{
			var go = Fsm.GetOwnerDefaultTarget(gameObject);
			if (go == null)
			{
				return;
			}

			var goTarget = targetObject.Value;
			if (goTarget == null && targetPosition.IsNone)
			{
				return;
			}

			// re-initialize if game object has changed
			
			if (previousGo != go)
			{
				lastRotation = go.transform.rotation;
				desiredRotation = lastRotation;
				previousGo = go;
			}
			
			// desired look at position

			Vector3 lookAtPos;
			if (goTarget != null)
			{
				lookAtPos = !targetPosition.IsNone ?
					goTarget.transform.TransformPoint(targetPosition.Value) : 
					goTarget.transform.position;
			}
			else
			{
				lookAtPos = targetPosition.Value;
			}
			
			if (keepVertical.Value)
			{
				lookAtPos.y = go.transform.position.y;
			}
			
			// smooth look at

            var diff = lookAtPos - go.transform.position;
            if (diff != Vector3.zero && diff.sqrMagnitude > 0)
			{
				desiredRotation = Quaternion.LookRotation(diff, upVector.IsNone ? Vector3.up : upVector.Value);
			}

			lastRotation = Quaternion.Slerp(lastRotation, desiredRotation, speed.Value * Time.deltaTime);
			go.transform.rotation = lastRotation;
			
			// debug line to target
			
			if (debug.Value)
			{
				Debug.DrawLine(go.transform.position, lookAtPos, Color.grey);
			}

			// send finish event?

			if (finishEvent != null)
			{
				var targetDir = lookAtPos - go.transform.position;
				var angle = Vector3.Angle(targetDir, go.transform.forward);

				if (Mathf.Abs(angle) <= finishTolerance.Value)
				{
					Fsm.Event(finishEvent);
				}
			}
		}

	}
}

I apologize, but I am very new to scripting. I have been using Unity Playmaker lately and only in the past week have I started working on hand scripting. What am I doing wrong here? thanks for your time.