Another Alternating Weapon Fire issue....

Hi Everyone,
I’m really new to using Unity, but I’ve dabbled a little here and there with coding and design functions.

I’ve been following a few tutorials that have taught me a lot, but some of the tutorials don’t go into the depth of everything, so I’ve been piecing together what I can. I have this script called ‘Shooter’ and now the script works great when I keep it the way the tutorial had it, but my plan is to alternate the fire between to side weapons on a ship. Like I said, when the tutorial version of the script is enable, they both fire correctly at the same time. I’ve looked at numerous different approaches to ‘alternating weapon fire’, but none have seemed to work.

Below is the ‘Shooter’ script I have. The bottom portion of the script is where the issue is coming from. In the ‘If/Else’ statement, I can see the print ‘Test 1’ and ‘Test 2’ coming through, but not the print ‘Left Fire’, which means the line ‘Instantiate(projectile, leftMuzzle.position, leftMuzzle.rotation);’ is the causing issue.

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

public class Shooter : MonoBehaviour
{
    [SerializeField]
    float rateOfFire;
    [SerializeField]
    Projectile projectile;

    [HideInInspector]
    public Transform rightMuzzle;
    [HideInInspector]
    public Transform leftMuzzle;

    float nextFireAllowed;
    public bool canFire;

    private void Start()
    {
        canFire = true;
    }
    private void Awake(){
        rightMuzzle = transform.Find("PrimaryBlasterRightMuzzle");
        leftMuzzle = transform.Find("PrimaryBlasterLeftMuzzle");
    }

    public virtual void Fire(){
        if (Time.time > nextFireAllowed){
            nextFireAllowed = Time.time + rateOfFire;

            if (canFire == true){
                print("Test 1");
                Instantiate(projectile, rightMuzzle.position, rightMuzzle.rotation);
                canFire = false;
            }
            else{
                print("Test 2");
                Instantiate(projectile, leftMuzzle.position, leftMuzzle.rotation);
                print("Left Fire");
                canFire = true;
            }
            nextFireAllowed = 0f;
        }
    }

}

152579-playoutputconsole.jpg

I’d really appreciate any help someone can give. I would say that you don’t have to go full Barney on me, but understand that I don’t have a PhD is C# or Unity. Thanks.

Seems as though I’ve figured out my own problem. There is probably a better way to simplify the code, but this is the way it worked for me. Now I just need to figure out the ‘rate of fire’. Appreciate all who found interest in this article and I hope it helps someone else.

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

public class Shooter : MonoBehaviour
{
    [SerializeField]
    public float rateOfFire;
    [SerializeField]
    public Projectile projectile;


    [HideInInspector]
    public Transform rightMuzzle;
    [HideInInspector]
    public Transform leftMuzzle;

    float nextFireAllowed;
    public bool rightFire;
    public bool leftFire;

    public virtual void Start()
    {

    }
    private void Awake(){
        rightMuzzle = transform.Find("PrimaryBlasterRightMuzzle");
        leftMuzzle = transform.Find("PrimaryBlasterLeftMuzzle");
    }

    public virtual void FireRight(){
        
        if (Time.time < rateOfFire){
            nextFireAllowed = Time.time + rateOfFire;
            if (rightFire == true){
                print("TestRight 1");
                Instantiate(projectile, rightMuzzle.position, rightMuzzle.rotation);
                rightFire = false;
            }
            else {
                print("TestRight 2");
                rightFire = true;
            }
            nextFireAllowed = 0f;
        }
    }

    public virtual void FireLeft()
    {
        
        if (Time.time < rateOfFire){
            nextFireAllowed = Time.time + rateOfFire;
            if (leftFire == true)
            {
                print("TestLeft 1");
                Instantiate(projectile, leftMuzzle.position, leftMuzzle.rotation);
                leftFire = false;
            }
            else
            {
                print("TestLeft 2");
                leftFire = true;
            }
            nextFireAllowed = 0f;
        }
    }

}

Well done for figuring this out. Sometimes just saying a problem out loud to someone, or putting it out onto a forum is enough to spark ideas in your brain.

The way I have tackled rate of fire in the past is

1: InvokeRepeating() the function that makes you fire. This is a way to call a function ‘on a beat’

2: My preferred method is to set a bool called something like canFire, then, every time a weapon fires, call a Coroutine (a function that allows a yield delay). Your coroutine function might look something like this

IEnumerator DelayFiring()
    {
        canFire = false; //stop the gun from firing
        yield return new WaitForSeconds(fireDelay); //fireDelay is the float variable for the rate of fire you want to set
        canFire = true; //set the gun back to being able to fire
    }

Then all you have to do is wrap you firing code in an if that checks whether canFire == true

Good luck on your coding adventure.