Automatic Shooting Delay

Hello everyone, I’ve been trying all afternoon to make my automatic shooting function with a rate that I can set.

For example I would like the laser to shoot at the shootinRate value when I hold down Fire1.

Can someone point me in the right direction?

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Unity.VisualScripting;
using UnityEditor.Tilemaps;
using UnityEditor.XR;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [Header("Input Settings")]
    public bool useController;

    [Header("Dash Settings")]
    [SerializeField] float dashSpeed = 15f;
    [SerializeField] float dashDuration = 1.0f;
    [SerializeField] float dashCooldown = 1.0f;
    bool isDashing;
    bool canDash = true;

    [Header("Character attributes:")]
    public float movement_base_speed = 5.0f;
    public float crosshair_distance = 1.0f;
    public float laser_base_speed = 10.0f;


    [Space]
    [Header("Character statistics:")]
    public Vector2 movementDirection;
    public float movementSpeed = 1.0f;
    public bool shooting;



    [Space]
    [Header("References:")]
    public Rigidbody2D rb;
    public Animator animator;
    public GameObject crosshair;
    public GameObject laserPrefab;
    public int playerId = 0;

    [SerializeField] bool isAutomatic;
    [SerializeField] public float shootingRate = 1.0f;
    
    
    
 

    private void Start()
    {
        canDash = true;
        
    }

    void Update()
    {
      
        
        if (isDashing)
        {
            return;
        }

        

        ProcessInputs();
        Move();
        Animate();
        MoveCrosshair();
        Shoot();




    }

    void ProcessInputs()
    {
        movementDirection = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
        movementSpeed = Mathf.Clamp(movementDirection.magnitude, 0.0f, 1.0f);
        movementDirection.Normalize();

        
        if (isAutomatic)
        {
            shooting = Input.GetButton("Fire1");
          
            
        }
        else
        {
            shooting = Input.GetButtonDown("Fire1");
        }
      
    }

    void Move()
    {
        if (isDashing)
        {
            return;
        }
       
        rb.velocity = movementDirection * movementSpeed * movement_base_speed;

        if (Input.GetButtonDown("Dash") && canDash && movementDirection.magnitude > 0.0f)
        {
            StartCoroutine(Dash());

        }
        else
        {
            StopCoroutine(Dash());
        }

        

    }
    void Animate() {

        if (isDashing)
        {


            animator.SetFloat("Speed", 10f);

        }

        else
        {
            animator.SetFloat("Horizontal", movementDirection.x);
            animator.SetFloat("Vertical", movementDirection.y);
            animator.SetFloat("Speed", movementSpeed);
        }
    }

        private void MoveCrosshair()

        {

            Vector3 aim = new Vector3(Input.GetAxis("AimHorizontal"), Input.GetAxis("AimVertical"), 0.0f);



            if (aim.magnitude > 0.0f)

            {

                aim.Normalize();

                aim *= 5.5f;

                crosshair.transform.localPosition = aim;

                crosshair.SetActive(true);

            }

            else crosshair.SetActive(false);

        }

    void Shoot()
    {

        

        Vector2 shootingDirection = crosshair.transform.localPosition;
        shootingDirection.Normalize();

        if (shooting)
        {
         
            
                GameObject laser = Instantiate(laserPrefab, transform.position, Quaternion.identity);
                laser.GetComponent<Rigidbody2D>().velocity = shootingDirection * laser_base_speed;
                laser.transform.Rotate(0, 0, Mathf.Atan2(shootingDirection.y, shootingDirection.x) * Mathf.Rad2Deg);
                Destroy(laser, 2.0f);
            
        }
        
        }

            
            

        



       

   

   

   
    
    private IEnumerator Dash()
        {
            canDash = false;
            isDashing = true;
            rb.velocity = new Vector2(movementDirection.x * dashSpeed, movementDirection.y * dashSpeed);
            yield return new WaitForSeconds(dashDuration);
            isDashing = false;

            yield return new WaitForSeconds(dashCooldown);
            canDash = true;
        }






    }

Thank you it works!

I’d like the first shot to be fired immediately upon press like you said but it doesn’t work, there a slight delay before the character begins to fire. Sorry I’m quite new to to this I may have misunderstood something.

The code looks like this now:

[SerializeField] bool isAutomatic;
[SerializeField] public float shootingInterval = 0.0f;

private void Start()
{
    canDash = true;
}

private void Awake()
{
    shootTimer = 0f;
}

void Update()
{
    shootTimer += (shooting) ? Time.deltaTime : 0f;
    if (shootTimer >= 0f && isAutomatic)
    {
        shootTimer -= 1f / shootingInterval;
        Shoot();
    }
}

You need a timer - Something like this:

Declare a timer

float shootTimer;

void Awake()
{
  shootTimer = 0f;
}

Run it

void Update()
{
  shootTimer += (shooting)?Time.deltaTime:-shootTimer;
  while(shootTimer > 0f && isAutomatic)
  {
    shootTimer -= shootingInterval;
    Shoot();
  }
}

You should be good to copy paste this part as is.

It doesnt work, there’s still a delay before the firing starts, and the lower I set the value for shootingInterval, the longer it takes to start shooting, if I set it high like 50 it starts shooting immediately when I press the button. The interval between shots works though.