- Home /
Adding a delay for weapon switching
Hi there, I have a weapon switching script which I got from: https://www.youtube.com/watch?v=Dn_BUIVdAPg
I'm trying to add a delay between weapon switching but having trouble with it. Here's the script:
using UnityEngine;
public class PlayerWeapons : MonoBehaviour
{
public int currentWeapon = 0;
public float switchDelay = 0.5f;
public float railSwitchDelay = 1.0f;
private float nextSwitch;
void Start()
{
SelectWeapon();
}
void Update()
{
int previousWeaponSelected = currentWeapon;
// if scroll wheel up is pressed
if (Input.GetAxis("Mouse ScrollWheel") > 0f)
{
// if currentWeapon goes above the amount of weapons, go back to the first weapon, index 0
if (currentWeapon >= transform.childCount - 1)
currentWeapon = 0;
// otherwise, go to next weapon
else
currentWeapon++;
}
// if scroll wheel down is pressed
if (Input.GetAxis("Mouse ScrollWheel") < 0f)
{
// if currentWeapon is already at 0, go to the last child (weapon)
if (currentWeapon <= 0)
currentWeapon = transform.childCount - 1;
// otherwise, go to previous weapon
else
currentWeapon--;
}
// if number 1 is pressed
if (Input.GetKeyDown(KeyCode.Alpha1))
{
currentWeapon = 0;
}
// if number 2 is pressed
if (Input.GetKeyDown(KeyCode.Alpha2))
{
currentWeapon = 1;
}
// if number 3 is pressed
if (Input.GetKeyDown(KeyCode.Alpha3))
{
currentWeapon = 2;
}
// if number 4 is pressed
if (Input.GetKeyDown(KeyCode.Alpha4))
{
currentWeapon = 3;
}
if (previousWeaponSelected != currentWeapon && Time.time > switchDelay)
{
nextSwitch = Time.time + switchDelay;
SelectWeapon();
}
}
void SelectWeapon()
{
// ensure all weapon lines are disabled
GameObject[] weapons;
weapons = GameObject.FindGameObjectsWithTag("Weapon");
foreach (var weapon in weapons)
{
weapon.BroadcastMessage("DisableLine", SendMessageOptions.DontRequireReceiver);
}
// ensure the lightning hum sound stops when switching weapons
FindObjectOfType<AudioManager>().Stop("LightningHum");
// disable all weapons except the current
int i = 0;
// loop through all child objects of the object which has this script
foreach (Transform weapon in transform)
{
// if the first object is equal to 0, set the first object to active and set the other objects to inactive
if (i == currentWeapon)
weapon.gameObject.SetActive(true);
else
weapon.gameObject.SetActive(false);
i++;
}
}
}
The delay part which I have tried to implement is this bit:
if (previousWeaponSelected != currentWeapon && Time.time > switchDelay)
{
nextSwitch = Time.time + switchDelay;
SelectWeapon();
}
But it's not working, the weapons still switch instantly. The logic must be flawed, can anyone help me out? P.S. I have tried adding the same logic to each of the "if number key pressed" statements but that doesn't work either!
Thanks for any help!
Unless you switch weapon within the first half second, Time.time will always be greater than that.
The question is, do you want to prevent weapon switching for a given amount of time after a switch has already happened, or do you want the switch to happen only a given time after the input is received?
To clarify, I'm now trying to add a delay AFTER the weapon has been switched, before I can fire the weapon.
I'm having a hard time working this out. I've tried to add a coroutine like this (this is on the weapon script, not weapon switch script):
public WaitForSeconds switchDelay = new WaitForSeconds(0.5f);
private bool switching = false;
public IEnumerator SwitchDelay()
{
switching = true;
yield return switchDelay;
switching = false;
}
Then running the coroutine in the Start() function, since that will be executed every time the object is activated, right?
And then wrapping the 'if key pressed' statements in an if switching == false statement. So I should only be able to fire if the coroutine has finished, but this doesn't seem to work either. Here's the rest of the relevant code:
void Start()
{
StartCoroutine("SwitchDelay");
lightningLine = GetComponent<LineRenderer>();
source = GetComponent<AudioSource>();
}
void Update()
{
if (switching == false)
{
// Check if the player has pressed the fire button and if enough time has elapsed since they last fired
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.$$anonymous$$ouse0) && Time.time > nextFire)
{
// Update the time when our player can fire next
nextFire = Time.time + fireRate;
PlayerFireWeapon();
}
// to play the audio LightningFire & Hum only once.
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.$$anonymous$$ouse0))
{
FindObjectOfType<Audio$$anonymous$$anager>().Play("LightningFire");
FindObjectOfType<Audio$$anonymous$$anager>().Play("LightningHum");
}
if (Input.Get$$anonymous$$eyUp($$anonymous$$eyCode.$$anonymous$$ouse0))
{
FindObjectOfType<Audio$$anonymous$$anager>().Stop("LightningHum");
lightningLine.enabled = false;
muzzleFlash.Stop();
}
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.$$anonymous$$ouse1))
PlayerFireAlternative();
}
}
I think I worked it out by using the coroutine in the OnEnable function ins$$anonymous$$d of Start :) Will do some testing and report back!
Edit: Yeah it works
Answer by UnityCoach · Sep 15, 2017 at 12:39 PM
You probably wanted to write :
if (previousWeaponSelected != currentWeapon && Time.time > nextSwitch)
{
nextSwitch = Time.time + switchDelay;
SelectWeapon();
}
Oh, yeah you're right :) Thanks
However I just realised I'm doing this wrong. I don't want the actual weapon switching to have a delay, but I want there to be a delay AFTER switching weapons before you can shoot a weapon, i.e. during the (currently non-existant) switch animation.
So I'm just trying to work that out :)
Your answer
Follow this Question
Related Questions
Non Spammable Skill/Button 1 Answer
How do I delay an Ad? 2 Answers
Multiple Cars not working 1 Answer
Function delay? 1 Answer
Distribute terrain in zones 3 Answers