What’s the actual problem with the code? Seems roughly okay on a quick look. You should describe specifically what isn’t working. Otherwise maybe you’ll just get comments like, “Change the ‘20’ to ‘30’, that should do it…”
One approach is to declare a private float variable in your class called _lastShotTime, or something like that. When you actually fire the gun, set _lastShotTime to Time.timeSinceLevelLoad. Now, right at the beginning of your Shoots() method, check whether (Time.timeSinceLevelLoad - _lastShotTime) is greater than some constant firing rate. If it’s not, you return, and you don’t fire anything. But if enough time has passed, you proceed with shooting.
Is this right? Sorry if it isn’t i’m kinda new to C#
Right Now its giving me an error that float does not contain a definition for ‘timeSinceLevelLoad’
using UnityEngine;
using System.Collections;
public class m4Gun : MonoBehaviour
{
public float damage = 20f;
public float range = 100f;
public float impactforce = 30f;
public int maxAmmo = 30;
public int currentAmmo;
public float reloadTime = 5f;
public ParticleSystem m4muzzleFlash;
private bool isReloading = false;
public Camera fpsCam;
private float _lastShotTime;
public Animator animator;
void Start()
{
currentAmmo = 30;
}
void OnEnable ()
{
isReloading = false;
animator.SetBool("Reloading", false);
}
// Update is called once per frame
void Update()
{
if (isReloading)
return;
if (currentAmmo <= 0)
{
StartCoroutine(Reload());
return;
}
if (Input.GetButton("Fire1"))
{
if (_lastShotTime.timeSinceLevelLoad - _lastShotTime > 0.25f)
return;
else
_lastShotTime = _lastShotTime.timeSinceLevelLoad;
Shoots();
}
}
IEnumerator Reload()
{
isReloading = true;
Debug.Log("Reloading...");
animator.SetBool("Reloading", true);
yield return new WaitForSeconds(reloadTime - .25f);
animator.SetBool("Reloading", false);
yield return new WaitForSeconds(.25f);
currentAmmo = maxAmmo;
isReloading = false;
}
void Shoots ()
{
m4muzzleFlash.Play();
currentAmmo--;
RaycastHit hit;
if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
{
Debug.Log(hit.transform.name);
Target target = hit.transform.GetComponent<Target>();
if (target != null)
{
target.TakeDamage(damage);
}
if (hit.rigidbody != null)
{
hit.rigidbody.AddForce(-hit.normal * impactforce);
}
}
}
}
‘Time’ is a special class in Unity. ‘Time.timeSinceLevelLoad’ gets the number of seconds since the level was loaded. You can’t call ‘timeSinceLevelLoad’ on just anything.
You’ve also got the logic a little reversed. You should return if the value is < 0.25f, not > 0.25f.
And most of all, you’ve completely broken your code due to your lack of curly braces. If you don’t use curly braces with an if/else, then only the immediate next line gets included in the if/else. So, in the case of your ‘else’, since you didn’t use curly braces, the “Shoots()” call isn’t part of the if/else at all, and it will be called regardless of the shot timer you set up.
My suggestion is to just always use curly braces to avoid these kinds of simple (but easy to make) mistakes, until you’re enough of a rockstar developer that you start to have strong opinions about curly braces.
Anyway, the following is probably correct:
if (Input.GetButton("Fire1"))
{
if (Time.timeSinceLevelLoad - _lastShotTime < 0.25f) {
return;
} else {
_lastShotTime = Time.timeSinceLevelLoad;
Shoots();
}
}