- Home /
Shooting every second issue
I have a shooting script that only allows the player to shoot one projectile every second (so they can't spam). Except if I wait a bit, on the first shot, the player shoots 2 projectiles. How can I fix this? Here's my code:
//variables for shooting
var canShoot:boolean=true;
var timeToShoot:float=1;
var currentShootingTime:float=0;
//projectile array
var projectiles : Transform[];
enum ProjType { RPG, RPBR,BR1 }
var currProj = ProjType.RPG;
//Initializing currentTime
function Start()
{
currentShootingTime=Time.time+timeToShoot;
}
function FixedUpdate()
{
//connects to my animator controller
var Tmation:Animator=GetComponent(Animator);
//Projectile Selection
if (Input.GetKeyDown("1")) currProj=ProjType.RPG;
if (Input.GetKeyDown("2")) currProj=ProjType.RPBR;
if (Input.GetKeyDown("3")) currProj=ProjType.BR1;
if (Input.GetButtonDown("Jump") && canShoot){
//if space bar is pressed, normal shoot animation
Tmation.SetBool("Fire", true);
var projectile=Instantiate(projectiles[currProj], transform.FindChild("CannonPoint").transform.position, Quaternion.identity);
//tags projectile, gets speed of tank and multiplies it by 3000 for the RPG
switch(currProj) {
case ProjType.RPG:
projectile.gameObject.tag="projectile";
projectile.rigidbody.AddForce(transform.forward*4000);
//recoil
rigidbody.AddRelativeForce(Vector3(0,0,-1000000));
break;
case ProjType.RPBR:
projectile.gameObject.tag="BouncyRocket";
projectile.rigidbody.AddForce(transform.forward*50000);
projectile.rigidbody.AddForce(transform.up*7000);
//recoil
rigidbody.AddRelativeForce(Vector3(0,0,-1000000));
break;
case ProjType.BR1:
projectile.gameObject.tag="BuildingRocket";
projectile.rigidbody.AddForce(transform.forward*500);
projectile.rigidbody.AddForce(transform.up*500);
break;
}
//shooting off for 1 second
canShoot=false;
}else{
Tmation.SetBool("Fire", false);
}
if (!canShoot){
checkShoot();
}
}
//shooting timer
function checkShoot()
{
if(Time.time > currentShootingTime)
{
canShoot = true;
currentShootingTime = Time.time + timeToShoot;
}
}
I appreciate your help. -Hyperion
Did you debug? what did you get out of your debugging session? - if you don't know how to debug, or don't debug, I highly suggest that you learn/do debugging. It will save you a ton of headaches. Sometimes users don't bother reading long code. With debugging, you can narrow down your problem to something very specific so that there's more appetite to answer your question :P
Sorry for the long code, I thought it's simple enough to put like this. Because it really is simple, but people ask "what about other code you might have that might be the problem" so I included all of it. $$anonymous$$y issue is the time checking inside the check shoot function, because without it, my player doesn't shoot 2 projectiles at once randomly. Yes, I know how to debug, but what will that do on a script that works (no errors)? Won't it just pass through happily? Plus my problem is narrowly put as the title of the question. But thank you for your suggestion, I will have that in $$anonymous$$d next time.
Edit: oops never$$anonymous$$d you set currentShootingTime. $$anonymous$$aybe Time.Time will be greater than Time.Time+1 when it hits that first shot loop with canshoot = true, which is then set to false, which then calls checkshoot which would set canshoot back to true if time.time > time.time+1 (from start).
Answer by kork · Sep 03, 2013 at 10:03 AM
The problem is the last piece of code:
//shooting off for 1 second
canShoot=false;
// ...
if (!canShoot){
checkShoot();
}
You just shot a shot and set canShoot to false. When you call checkShoot() now, the time will be updated, but canShoot will also be set to true as well. Thats why you can place two shots at once if you wait over your timeframe.
To make sure that you can only fire a shot when it's allowed you should wrap your shooting code with an if-statement like this:
if (Input.GetButtonDown("Jump") && checkShoot()) { // when the button is pressed and we may shoot right now
// we want to shoot now. Let's first record the time when we will be allowed to shoot next.
currentShootingTime = Time.time + timeToShoot;
// do the rest of your shooting code. (basically insert your code here)
}
// This function simply checks if the current time is past the next allowed shooting time. If so , it returns true, otherwise it returns false.
function checkShoot()
{
return (Time.time > currentShootingTime);
}
Basically your first approach failed because you had two checks that checked for the same information but could diverge (e.g. canShoot == true vs Time.time >= timeToShoot). By removing one of the checks and only using the Time.time >= timeToShoot you will no longer get divergent results and the code will work as inteded. I would almost always refrain from using boolean flags for state decisions as it is easy to make mistakes there.
Thank you very much! Would you be kind enough to explain how the script works so I could understand the concept?
I added some more explanations on why your code failed and what the suggested code does different. Hope this helps :).
Your answer
Follow this Question
Related Questions
Shooting in 2 dimensional games 2 Answers
Gun Fire, sparks on Collision 1 Answer
Cannon shoots in wrong direction with unrealisic Physic 1 Answer
How to avoid speed change in bullets while moving? 1 Answer
Shooting projectiles in 2D world 2 Answers