Cant seem to make my camera recoil with gun

image
My Hierachy looks like this, and my recoil script is on “AK-47”. When firing the gun, my gun moves, while my camera is still, and it looks awful. The gun recoils and gradually rotates to point fairly high in the sky, while the camera is looking forward.

I tried to move my script to my main camera however, when I did so I lost all ability to look up and down. Moving side to side worked, but my gun doesn’t recoil at all now, its a stiff as a board.

using UnityEngine;

public class RecoilController : MonoBehaviour
{
    [Header("Recoil Settings")]
    [SerializeField] private float snappiness;
    [SerializeField] private float returnSpeed;

    public Camera playerCamera; // Reference to the camera

    private Vector3 currentRotation;
    private Vector3 targetRotation;

    //Hipfire Recoil
    [SerializeField] private float recoilX;
    [SerializeField] private float recoilY;
    [SerializeField] private float recoilZ;

    

    private void Start()
    {

    }

    public void ApplyRecoil()
    {
        targetRotation += new Vector3(recoilX, Random.Range(-recoilY, recoilY), Random.Range(-recoilZ, recoilZ));

    }

    private void Update()
    {
        targetRotation = Vector3.Lerp(targetRotation, Vector3.zero, returnSpeed *  Time.deltaTime);
        currentRotation = Vector3.Slerp(currentRotation, targetRotation, snappiness * Time.fixedDeltaTime);
        transform.localRotation = Quaternion.Euler(currentRotation);

    }
}

And here below is my Gun Controller script

using System.Collections;
using UnityEngine;
using UnityEngine.UI;

public class GunController : MonoBehaviour
{
    [Header("Gun Settings")]
    public float fireRate = 0.1f;
    public int clipSize = 30;
    public int reservedAmmoCapacity = 270;

    // Variables that change throughout code
    private bool _canShoot;
    private int _currentAmmoInClip;
    private int _ammoInReserve;

    // Muzzleflash
    public Image muzzleFlashImage;
    public Sprite[] flashes;

    // muzzle
    public Transform muzzle;

    // Aiming
    public Vector3 normalLocalPosition;
    public Vector3 aimingLocalPosition;

    public float aimSmoothing = 10;

    //recoil reference
    public RecoilController recoilController;

    //recoil force
 


    //visual cues
    public LineRenderer bulletTrajectoryLine;



    //Audio
    AudioSource m_shootingSound;


    private void Start()
    {
        _currentAmmoInClip = clipSize;
        _ammoInReserve = reservedAmmoCapacity;
        _canShoot = true;
        recoilController = GetComponent<RecoilController>();
        m_shootingSound = GetComponent<AudioSource>();

        bulletTrajectoryLine = GetComponent<LineRenderer>();
        bulletTrajectoryLine.positionCount = 2;
        bulletTrajectoryLine.SetPosition(0, muzzle.transform.position);
        bulletTrajectoryLine.SetPosition(1, muzzle.transform.position + muzzle.transform.forward * 10);
    }

    private void Update()
    {



        
        DetermineAim();
        Debug.DrawRay(muzzle.transform.position, muzzle.transform.forward * 10, Color.red, 1);
        if (Input.GetMouseButton(0) && _canShoot && _currentAmmoInClip > 0)
        {
            _canShoot = false;
            _currentAmmoInClip--;
            StartCoroutine(ShootGun()); //Shooting initialize

            
            recoilController.ApplyRecoil();
        }
        else if (Input.GetKeyDown(KeyCode.R) && _currentAmmoInClip < clipSize && _ammoInReserve > 0)
        {
            int amountNeeded = clipSize - _currentAmmoInClip;

            if (amountNeeded >= _ammoInReserve)
            {
                _currentAmmoInClip += _ammoInReserve;
                _ammoInReserve -= amountNeeded;
            }
            else
            {
                _currentAmmoInClip = clipSize;
                _ammoInReserve -= amountNeeded;
            }
        }
    }

    private void DetermineAim()
    {
        Vector3 target = normalLocalPosition;
        if (Input.GetMouseButton(1))
            target = aimingLocalPosition;

        Vector3 desiredPosition = Vector3.Lerp(transform.localPosition, target, Time.deltaTime * aimSmoothing);

        transform.localPosition = desiredPosition;
    }




    private IEnumerator ShootGun()
    {
        
        StartCoroutine(MuzzleFlash());
        recoilController.ApplyRecoil();
        RaycastForEnemy();

        yield return new WaitForSeconds(fireRate);
        _canShoot = true;




        m_shootingSound.Play(); //Shooting Sound
    }


    private void RaycastForEnemy()
    {
        RaycastHit hit;
        if (Physics.Raycast(muzzle.transform.position, muzzle.transform.forward, out hit, 1 << LayerMask.NameToLayer("Enemy")))
        {
            try
            {
                Debug.Log("Hit an Enemy!");


                Rigidbody rb = hit.transform.GetComponent<Rigidbody>();
                rb.constraints = RigidbodyConstraints.None;
                rb.AddForce(muzzle.transform.forward * 500);

                // Update the endpoint of the bulletTrajectoryLine to the hit position
                bulletTrajectoryLine.SetPosition(1, hit.point);
                bulletTrajectoryLine.SetPosition(0, muzzle.transform.position);
            }
            catch
            {

            }

        }

        else
        {
            // If the raycast didn't hit an enemy, set the endpoint of the bulletTrajectoryLine to a point far ahead
            float maxDistance = 100f;
            bulletTrajectoryLine.SetPosition(1, muzzle.transform.position + muzzle.transform.forward * maxDistance);
            bulletTrajectoryLine.SetPosition(0, muzzle.transform.position);
        }



    }

    private IEnumerator MuzzleFlash()
    {
        muzzleFlashImage.sprite = flashes[Random.Range(0, flashes.Length)];
        muzzleFlashImage.color = Color.white;
        yield return new WaitForSeconds(0.05f);
        muzzleFlashImage.sprite = null;
        muzzleFlashImage.color = new Color(0, 0, 0, 0);
    }


}

AK47 is a child object of Camera meaning any rotation applied to AK47 won’t apply to any of its parent objects including Camera, however it will apply to any child object of AK47.
Meaning instead of applying the recoil to the gun, apply it the Camera object only, and it’ll affect all its child objects including AK47.