- Home /
Having a strange problem with yield and instantiate (C#)
I'm having a strange problem. I want to make it so if the space bar is pressed, the player shoots a projectile every few seconds. I've tried 2 techniques so far, and the common theme seams to be that if the projectile is set to instantiate every 0 seconds, it explodes like crazy; anything greater, it makes a solid line with some glitchy movements.
Here are some screenshots: http://imgur.com/aRRMThO
If you can think of any way I could space out the projectiles more, or why this is happening it would be very much appreciated.
using System.Collections;
public class player : MonoBehaviour {
private Transform ship;
public int shipspeed = 5;
public Transform shotPos;
public float shotForce = 1000f;
public Rigidbody projectile;
bool con = true;
void Start () {
//spawn position
ship = transform;
ship.position = new Vector3(0, -7, 2);
}
void Update () {
//Horizontal movement with arrow keys
ship.Translate(Vector3.right * shipspeed * Input.GetAxis("Horizontal") * Time.deltaTime);
//ship wrapping
if(ship.position.x > 6){
ship.position = new Vector3(-6, -7, 2);
}
else if(ship.position.x < -6){
ship.position = new Vector3(6, -7, 2);
}
//gun
if(Input.GetButton("Jump")){
StartCoroutine("Fire");
}
if(Input.GetButtonUp("Jump")){
StopCoroutine("Jump");
}
}
//luanch projectile
void Shoot (){
Rigidbody shot = Instantiate(projectile, shotPos.position, shotPos.rotation) as Rigidbody;
shot.AddForce(shotPos.up * shotForce);
}
//gun delay loop
IEnumerator Fire(){
while(con == true){
Shoot ();
yield return new WaitForSeconds(1f);
}
}
}
Have you tried increasing the wait time? Also, i'm not very experienced w/C#, but I know that it's a fact for javascript that when you use the regular Update() function to run other function that even on a clock, the speed of routines is deter$$anonymous$$ed by the run speed of your project.
Answer by Life Alchemist · Sep 01, 2013 at 04:47 AM
Don't use StartCoroutine and yields in this case. It slows things down when you want things to be instantaneous.
using UnityEngine;
using System.Collections;
public class shootGun : MonoBehaviour {
bool shotCooldown;
private float timer;
private float cooldown;
// Use this for initialization
void Start () {
shotCooldown = false;
timer = 0.0f;
cooldown = 1.0f;
}
// Update is called once per frame
void Update () {
if(Input.GetButton("Fire")){ //jump, fire, whatever you want the key to be
Shoot();
}
if (shotCooldown == true)
{
if (timer < cooldown)
timer += Time.deltaTime;
else
{
shotCooldown = false;
timer = 0.0f;
}
}
}
//luanch projectile
void Shoot (){
if(shotCooldown == false)
{
Rigidbody shot = Instantiate(projectile, shotPos.position, shotPos.rotation) as Rigidbody;
shot.AddForce(shotPos.up * shotForce);
shotCooldown = true;
}
}
}
If you can, try to use less spacing in-between sections of code. Change the cooldown variable to however long you want the interval between shots to be.
A more standard "Unity" way is to make timer
be a real time in seconds, so it stands for "can shoot again when the clock says this." After a shot, set it to Time.time+coolDownSecs;
. Before you shoot, check if if(Time.time>=timer)
.
Avoids the need to hand-add time each frame -- Unity runs the clock for you.
Ah, what Owen says is good in this case. Since you're calling it and there isn't a need to check anything else except fire key, using Time.time+coolDownSecs is better for "efficient code." Otherwise, they do the same thing if you're not concerned.
Your answer
![](https://koobas.hobune.stream/wayback/20220613113340im_/https://answers.unity.com/themes/thub/images/avi.jpg)