So I am using Unity’s new Input system to handle shooting my gun, I will be using a Gamepad.
The issue I have is, I can only tap the “Shoot” input (Right Trigger) to fire the gun.
I want to be able to hold down the trigger and shoot so it’s like an assault rifle.
I then want it to instantly stop shooting once I release the “Shoot” input.
How do I achieve this? This is my code…
using UnityEngine;
using TMPro;
using UnityEngine.InputSystem;
using System.Collections;
public class Gun : MonoBehaviour
{
public float damage = 10f;
public float range = 100f;
public float fireRate = 15f;
public float raycastOffset = 0.5f;
public float maxAmmo = 30f;
public float reservedAmmo = 120f;
public float reloadTime = 2f;
public TMP_Text ammoText;
private Camera fpsCam;
private float nextTimeToFire = 0f;
private float currentAmmo;
private PlayerControls controls;
private bool canShoot = true;
void Awake()
{
controls = new PlayerControls();
controls.Player.Shoot.performed += ctx => Shoot();
controls.Player.Reload.performed += ctx => StartCoroutine(ReloadWithDelay());
}
void OnEnable()
{
controls.Player.Enable();
}
void OnDisable()
{
controls.Player.Disable();
}
void Start()
{
fpsCam = Camera.main;
currentAmmo = maxAmmo;
UpdateAmmoText();
}
// Update is called once per frame
void Update()
{
if (Time.time >= nextTimeToFire && currentAmmo > 0)
{
if (controls.Player.Shoot.triggered)
{
nextTimeToFire = Time.time + 1f / fireRate;
Shoot();
currentAmmo--; // Decrease ammo count after shooting
UpdateAmmoText();
}
}
// Draw debug ray
Debug.DrawRay(fpsCam.transform.position + fpsCam.transform.forward * raycastOffset, fpsCam.transform.forward * range, Color.red);
// Disable shoot input when currentAmmo reaches 0
if (currentAmmo <= 0)
{
controls.Player.Shoot.Disable();
}
else
{
controls.Player.Shoot.Enable();
}
}
void Shoot()
{
RaycastHit hit;
if (Physics.Raycast(fpsCam.transform.position + fpsCam.transform.forward * raycastOffset, fpsCam.transform.forward, out hit, range))
{
Debug.Log(hit.transform.name);
Target target = hit.transform.GetComponent<Target>();
if (target != null)
{
target.TakeDamage(damage);
}
}
}
IEnumerator ReloadWithDelay()
{
yield return new WaitForSeconds(reloadTime);
if (currentAmmo < maxAmmo && reservedAmmo > 0)
{
int ammoNeeded = (int)(maxAmmo - currentAmmo);
int ammoToReload = Mathf.Min(ammoNeeded, (int)reservedAmmo);
currentAmmo += ammoToReload;
reservedAmmo -= ammoToReload;
UpdateAmmoText();
if (currentAmmo > 0)
{
canShoot = true; // Enable shooting after reload
}
}
}
void UpdateAmmoText()
{
if (ammoText != null)
{
ammoText.text = currentAmmo.ToString("00") + " | " + reservedAmmo.ToString("00");
}
}
}