Hi,
So, it’s my first time posting, as I’m entirely new to Unity, and as a means of learning how to code and familiarizing myself with the 3D Built-In Render Pipeline, I’ve been following a series of tutorials on YouTube, which I’ll link to below, and it’s been going great up until today, where I’ve been experiencing a problem that I haven’t been able to solve after watching and re-watching the segment on implementing a procedural recoil system.
In the video, the author demonstrates how to write a C# script for managing the recoil function in order to move a Cinemachine virtual camera back and forth in sync with the weapon firing, which is attached to the weapon game-object, which I believe I have accurately reproduced, however, because of my ongoing confusion, I’m honestly beginning to question myself on that due to the fact that in testing, the camera isn’t behaving as it should according to the tutorial. Following the writing of the recoil script, the author outlined the necessary additions to the WeaponManager script from previous lessons in the series, which I’m pretty sure I also reproduced correctly, but again, I’m not so sure any more.
To be entirely frank, I have no idea what I’m missing here, but my theory is that maybe it has something to do with my in-Unity setup of the components being used by the relevant game objects? I’m not sure if maybe my vitrual camera or my recoilFollowPos game object or possibly cinemachine itself has been somehow misconfigured by my setting up of the components with some potentially incorrect parameters or something? I honestly have no clue, however I have screenshots of my project hierarchy and the inspectors for the relevant game objects that I am also able to provide, if that helps?
My weapon recoil code is as follows:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WeaponRecoil : MonoBehaviour
{
[SerializeField] Transform recoilFollowPos;
[SerializeField] float kickBackAmount = -1;
[SerializeField] float kickBackSpeed = 10, returnSpeed = 20;
float currentRecoilPosition, finalRecoilPosition;
// Update is called once per frame
void Update()
{
currentRecoilPosition = Mathf.Lerp(currentRecoilPosition, 0, returnSpeed * Time.deltaTime);
finalRecoilPosition = Mathf.Lerp(finalRecoilPosition, currentRecoilPosition, kickBackSpeed * Time.deltaTime);
recoilFollowPos.localPosition = new Vector3(0, 0, finalRecoilPosition);
}
public void TriggerRecoil()
{
currentRecoilPosition += kickBackAmount;
}
}
My WeaponManager code is as follows:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WeaponManager : MonoBehaviour
{
[Header("Fire Rate")]
[SerializeField] float fireRate;
float fireRateTimer;
[SerializeField] bool semiAuto;
[Header("Bullet Properties")]
[SerializeField] GameObject bullet;
[SerializeField] Transform barrelPos;
[SerializeField] float bulletVelocity;
[SerializeField] int bulletsPerShot;
AimStateManager aim;
[SerializeField] AudioClip gunShot;
AudioSource audioSource;
WeaponAmmo ammo;
ActionStateManager actions;
WeaponRecoil recoil;
// Start is called before the first frame update
void Start()
{
recoil = GetComponent<WeaponRecoil>();
audioSource = GetComponent<AudioSource>();
aim = GetComponentInParent<AimStateManager>();
ammo = GetComponent<WeaponAmmo>();
actions = GetComponentInParent<ActionStateManager>();
fireRateTimer = fireRate;
}
// Update is called once per frame
void Update()
{
if(ShouldFire()) Fire();
}
bool ShouldFire()
{
fireRateTimer += Time.deltaTime;
if (fireRateTimer < fireRate) return false;
if (ammo.currentAmmo == 0) return false;
if (actions.currentState == actions.Reload) return false;
if (semiAuto && Input.GetKeyDown(KeyCode.Mouse0)) return true;
if (!semiAuto && Input.GetKey(KeyCode.Mouse0)) return true;
return false;
}
void Fire()
{
fireRateTimer = 0;
barrelPos.LookAt(aim.aimPos);
audioSource.PlayOneShot(gunShot);
recoil.TriggerRecoil();
ammo.currentAmmo--;
for(int i =0; i < bulletsPerShot; i++)
{
GameObject currentBullet = Instantiate(bullet, barrelPos.position, barrelPos.rotation);
Rigidbody rb = currentBullet.GetComponent<Rigidbody>();
rb.AddForce(barrelPos.forward * bulletVelocity, ForceMode.Impulse);
}
}
}
The lines in the WeaponManager that are relevant to calling the recoil functions are the following:
WeaponRecoil recoil; //Declared in the public class on line 23
recoil = GetComponent<WeaponRecoil>(); //Within the start method on line 28
recoil.TriggerRecoil(); //Within the Fire method on line 58
Youtube Links:
The playlist for the YouTube tutorials that I’m following can be found here: https://www.youtube.com/playlist?list=PLX_yguE0Oa8QmfmFiMM9_heLBeSA6sNKx
The video pertaining to the issue in question is " Third Person Shooter (Unity Tutorial) Ep 9 Procedural Recoil & Gunshot VFX," which can be found here: https://youtu.be/k8s3EgoYKX4?si=5kCWfpw67r0pHSk7
To anyone who’s read through all of this and looked over the information I’ve provided, thank you so much for your time, even if you aren’t able to help. I greatly appreciate you taking the time regardless of the outcome, and to anyone who is able to help or even just flat out point out the solution, thank you so much in advance. I am infinitely grateful to any and all of you, and I hope you have a lovely day or night in whichever timezone you find yourself in.
Best regards,
-Stef.