Switching Firing Modes

I’ve searched all over to find a way to do this and spent 2 days doing so with no luck.

So far, I have an x-wing style ship with 4 laser turrets. I have a script to fire all 4 at once, but I need to find a way, to switch between 3 firing modes…all 4, 2 turrets alternating with the other 2 and one after the other in order.

This is the script for all 4 (could this be done any tidier also?)…

using UnityEngine;
using System.Collections;

public class XW_Shooting : MonoBehaviour {

public GameObject bullet_prefab;
public float bulletImpulse = 20f;
public float xwFireRate = 1f;
private float xwFire = 0.0f;
Transform gunTip1;
Transform gunTip2;
Transform gunTip3;
Transform gunTip4;
public AudioClip shoot;

void Start () 
{
	gunTip1 = GameObject.Find ("GuntipLT").transform;
	gunTip2 = GameObject.Find ("GuntipRT").transform;
	gunTip3 = GameObject.Find ("GuntipLB").transform;
	gunTip4 = GameObject.Find ("GuntipRB").transform;

}

			
// Update is called once per frame

void Update (){
	if (Input.GetButton ("Fire1") && Time.time > xwFire) {
		xwFire = Time.time + xwFireRate;

		GameObject thebullet = (GameObject)Instantiate (bullet_prefab, gunTip1.transform.position + transform.forward, transform.rotation);
		thebullet.rigidbody.AddForce (transform.forward * bulletImpulse, ForceMode.Impulse);
		audio.PlayOneShot(shoot);

		gunTip2 = GameObject.Find ("GuntipRT").transform;

		GameObject thebullet2 = (GameObject)Instantiate (bullet_prefab, gunTip2.transform.position + transform.forward, transform.rotation);
		thebullet2.rigidbody.AddForce (transform.forward * bulletImpulse, ForceMode.Impulse);
		audio.PlayOneShot(shoot);
		
		gunTip3 = GameObject.Find ("GuntipLB").transform;
		
		GameObject thebullet3 = (GameObject)Instantiate (bullet_prefab, gunTip3.transform.position + transform.forward, transform.rotation);
		thebullet3.rigidbody.AddForce (transform.forward * bulletImpulse, ForceMode.Impulse);
		audio.PlayOneShot(shoot);
		
		gunTip4 = GameObject.Find ("GuntipRB").transform;
		
		GameObject thebullet4 = (GameObject)Instantiate (bullet_prefab, gunTip4.transform.position + transform.forward, transform.rotation);
		thebullet4.rigidbody.AddForce (transform.forward * bulletImpulse, ForceMode.Impulse);
		audio.PlayOneShot(shoot);

	}
}

}

Thanks for looking!

2 Answers

2

Sometimes in solving a problem like this one, all the current code gets in the way, and it can be helpful to backup and solve the specific problem in simpler code.

using UnityEngine;
using System.Collections;

public class Example : MonoBehaviour {

	public enum Sequence { ALLFOUR, TWOBYTWO, INORDER };

	public Sequence seq = Sequence.INORDER;

	void Update() {
		if (Input.GetKeyDown(KeyCode.Space)) {
			StartCoroutine(Fire(seq));
		}
	}

	IEnumerator Fire(Sequence seq) {
		switch(seq) {
		case Sequence.ALLFOUR:
			Fire(1);
			Fire(2);
			Fire(3);
			Fire(4);
			break;
		case Sequence.TWOBYTWO:
			Fire(1);
			Fire(2);
			yield return new WaitForSeconds(0.3f);
			Fire(3);
			Fire(4);
			break;
		case Sequence.INORDER:
			Fire(1);
			yield return new WaitForSeconds(0.3f);
			Fire(2);
			yield return new WaitForSeconds(0.3f);
			Fire(3);
			yield return new WaitForSeconds(0.3f);
			Fire(4);
			break;
		}
	}

	void Fire(int which) {
		Debug.Log ("Firing " + which);
	}
}

This might break with "Not all code paths return a value". Put a yield return null in at the end of the coroutine to fix.

I'm sorry I didn't mention the key press thing beforehand. Very kind of you to continue to help me :) I shall try and incorporate these ideas into the script. I will look into arrays though, as I'm sure it could be less cluttered. It may even help with the audio being played in the correct 3d space...that's another thread though. Cheers

You really need to sort our your plain English descriptions first. Code and structure will flow naturally from a decent functional description.

To answer based on your comments you could put a loop in that waits for input before firing the next bullet in @robertbu’s solution.

while (!Input.GetKeyDown(KeyCode.Space)) {
    yield return null;
}

Pseudo code could look something like this

var fireMode;

void Start (){
    StartCoroutine("Fire")
}

IEnumerator Fire (){
    switch (fireMode){
    case 1:
        while (true){
            for (int i = 0; i<noOfGuns; i++){
                yield return new WaitForSeconds(firingDelay);
                while (!Input.GetKeyDown(KeyCode.Space)) yield return null;
                FireGun(i);
            }
        }
    .. Other cases
    } 
}

public void ChangeFireMode (newFireMode){
    // Change fire mode
    StoptCoroutine("Fire")
    StartCoroutine("Fire")
}

Alternatively you could use a collection to determine which gun to fire next and iterate through that. You could build a custom collection that automatically cycles through the guns infinitely.

Yes, I apologize for not stating things. Sometimes these things are in my head for so long that I think I've mentioned them :) Thanks for the example, I shall get stuck into it again soon.