Camera rotates when switching weapon.

Whenever I switch between the main weapon and sidearm, the camera’s rotation changes.

What is happening:

Camera rotation is handled in the gun script.

Gun Script (on each weapon):

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GunScript : MonoBehaviour
{
   
    public bool Auto = true;
    public float damagePerBullet = 20f;
   
    public float fireRate = 0.2f;
    public int clipSize = 30;
    public int reserveAmmoCap = 360;

    bool _canShoot;
    public int _ammoInClip;
    public int _ammoInReserve;

    public ParticleSystem MuzFlash;

    public Vector3 normalLocalPos;
    public Vector3 aimingLocalPos;
    public float aimSmoothing = 0.2f;
    public float mouseSens = 1;
    public float weaponSway = 1.25f;

    Vector2 _currRot;

    public Vector2 randomRecoilContraints;
    public GameObject Impact;
    public float resetTime;
    public float backfire = 0.1f;


    void Start()
    {
        Cursor.lockState = CursorLockMode.Locked;     
        _ammoInClip = clipSize;
        _ammoInReserve = reserveAmmoCap;
        _canShoot = true;
    }
    void Update()
    {
        DetermineAim();
        DetermineRot();
       
        if (Auto)
        {
            AutoShooting();
        }
        else if (!Auto)
        {
            SemiAutoShooting();
        }
    }
    void AutoShooting()
    {
        if (Input.GetMouseButton(0) && _canShoot && _ammoInClip > 0)
        {
            _canShoot = false;
            _ammoInClip--;
            StartCoroutine(ShootGun());
        }
        else if(Input.GetKeyDown(KeyCode.R) && _ammoInClip < clipSize && _ammoInReserve > 0)
        {
            int amtNeeded = clipSize - _ammoInClip;
            if (amtNeeded > _ammoInReserve)
            {
                _ammoInClip += _ammoInReserve;
                _ammoInReserve = 0;
            }
            else
            {
                _ammoInClip = clipSize;
                _ammoInReserve -= amtNeeded;
            }
            if (_ammoInReserve <= 0)
            {
                _ammoInReserve = 0;
            }
        }
    }
    void SemiAutoShooting()
    {
        if (Input.GetMouseButtonDown(0) && _canShoot && _ammoInClip > 0)
        {
            _canShoot = false;
            _ammoInClip--;
            StartCoroutine(ShootGun());
        }
        else if(Input.GetKeyDown(KeyCode.R) && _ammoInClip < clipSize && _ammoInReserve > 0)
        {
            int amtNeeded = clipSize - _ammoInClip;
            if (amtNeeded > _ammoInReserve)
            {
                _ammoInClip += _ammoInReserve;
                _ammoInReserve = 0;
            }
            else
            {
                _ammoInClip = clipSize;
                _ammoInReserve -= amtNeeded;
            }
            if (_ammoInReserve <= 0)
            {
                _ammoInReserve = 0;
            }
        }
    }
    IEnumerator ShootGun()
    {
        MuzFlash.Play();
        DetermineRecoil();
        DoImpactEffect();
        yield return new WaitForSeconds(fireRate);
        _canShoot = true;
        RaycastForEnemy();
    }

    private void DoImpactEffect()
    {
        RaycastHit hitB;
        if (Physics.Raycast(transform.parent.parent.position, transform.parent.parent.forward, out hitB))
        {
            GameObject ImpactGO = Instantiate(Impact, hitB.point, Quaternion.LookRotation(hitB.normal));
            Destroy(ImpactGO, 1.69f);
        }
    }

    void DetermineRot()
    {
        Vector2 mouseAxis = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));
        mouseAxis *= mouseSens;
        _currRot += mouseAxis;
        _currRot.y = Mathf.Clamp(_currRot.y, -90f, 90f);
        transform.localPosition += (Vector3)mouseAxis * weaponSway / 1000f;
        transform.root.localRotation = Quaternion.AngleAxis(_currRot.x, Vector3.up);
        transform.parent.parent.localRotation = Quaternion.AngleAxis(-_currRot.y, Vector3.right);
    }
    void DetermineAim()
    {
        Vector3 target = normalLocalPos;
        if (Input.GetMouseButton(1))
        {
            target = aimingLocalPos;
        }
        Vector3 desiredPos = Vector3.Lerp(transform.localPosition, target, Time.deltaTime * aimSmoothing);
        transform.localPosition = desiredPos;
    }
    void DetermineRecoil()
    {
        transform.localPosition -= Vector3.forward * backfire;
        StartCoroutine(ResetBackRecoil());

        float xRecoil = Random.Range(-randomRecoilContraints.x, randomRecoilContraints.x);
        float yRecoil = Random.Range(-randomRecoilContraints.y, randomRecoilContraints.y);

        Vector2 recoil = new Vector2(xRecoil, yRecoil);

        _currRot += recoil;
    }
    void RaycastForEnemy()
    {
        RaycastHit hit;
        if (Physics.Raycast(transform.parent.parent.position, transform.parent.parent.forward, out hit))
        {
            Target tgt = hit.transform.transform.GetComponent<Target>();
            if (tgt != null)
            {
                tgt.GetComponent<Target>().TakeDmg(damagePerBullet);
            }
        }
    }
    IEnumerator ResetBackRecoil()
    {
        yield return new WaitForSeconds(resetTime);
        transform.localPosition += Vector3.forward * backfire;
    }
}

Weapon Switching script (on Weapon Holder):

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WeaponSwitcher : MonoBehaviour
{
    public int SelectedGun = 0;

    void Start()
    {
        SelectGun();
    }

    void Update()
    {
        int prevSelectedGun = SelectedGun;
       
        if (Input.GetAxis("Mouse ScrollWheel") > 0f)
        {
            if (SelectedGun >= transform.childCount - 1)
            {
                SelectedGun = 0;
            }
            else
            {
                SelectedGun++;
            }
        }
        if (Input.GetAxis("Mouse ScrollWheel") < 0f)
        {
            if (SelectedGun <= 0)
            {
                SelectedGun = transform.childCount - 1;
            }
            else
            {
                SelectedGun--;
            }
        }
        if (Input.GetKeyDown(KeyCode.Alpha1) && transform.childCount >= 1)
        {
            SelectedGun = 0;
        }
        if (Input.GetKeyDown(KeyCode.Alpha2) && transform.childCount >= 2)
        {
            SelectedGun = 1;
        }

        if (prevSelectedGun != SelectedGun)
        {
            SelectGun();
        }
    }

    void SelectGun()
    {
        int i = 0;
       
        foreach (Transform gun in transform)
        {
            if (i == SelectedGun)
            {
                gun.gameObject.SetActive(true);
            }
            else
            {
                gun.gameObject.SetActive(false);
            }
            i++;
        }
    }
}

How do I fix it? I’ve tried a few methods I thought would work but since I’m new to Unity, nothing seems to work.

Figure out the flow of whatever drives the camera rotation.

Remove from that flow anything that involves the weapon, as that’s obviously not correct.

Keep in mind it could be that your weapon switch is actually rotating the entire player, but with a smooth capsule you cannot tell. Eliminate (or fix) that possibility first.

I fixed it. Thanks for the advice.

1 Like