- Home /
Shooting bullets OnMouseDrag, time delay issues
Hello,
I'm fairly new with OnMouseDrag and Coroutines in general.
What I want to accomplish:
I currently have movement setup on mouse drag. You drag the character back and forth across the screen. I want the character to be shooting while you are dragging.
Issue I am having:
It seems that OnMouseDrag fires a ridiculous amount of times. I have a BulletFire script that is being called from OnMouseDrag, and it is fireing multiple times per second. This results in wayyyy to many bullets being shot.
What I tried:
I've tried calling a coroutine from my OnMouseDrag method, but that routine gets called so many times, its actually doing nothing but delaying the initial shot.
IEnumerator wait(){
yield return new WaitForSeconds (0.5f);
bulletSpawnScript.FireBullet ();
}
void OnMouseDown()
{
screenPoint = Camera.main.WorldToScreenPoint(gameObject.transform.position);
offset = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
}
void OnMouseDrag()
{
Vector3 point = Camera.main.ScreenToWorldPoint(Input.mousePosition);
point.z = gameObject.transform.position.z;
point.y = gameObject.transform.position.y;
gameObject.transform.position = point;
//Shoot gun
StartCoroutine (wait ());
//callFireBullet ();
}
void callFireBullet() {
StartCoroutine (wait ());
}
So basically here i'm trying to call my shoot method while the mouse button is held down, but I want to be able to have a .5 second or 1 second delay in between calls. Any idea what I am doing wrong?
Help is appreciated! Thanks, JayOhhGames
Answer by Pyrian · Apr 20, 2014 at 11:30 PM
So, you'll want to track whether a bullet has been fired in the past half-second. Just set a bool to false, set it true when you fire, and set it back to false in the coroutine. Test that bool to decide whether to fire.
private bool RecentShot = false;
IEnumerator wait()
{
yield return new WaitForSeconds (0.5f);
RecentShot = false;
}
void OnMouseDrag()
{
// Do your stuff
if (!RecentShot)
{
RecentShot = true;
callFireBullet ();
StartCoroutine (wait ());
}
}
Thanks this is exactly what I was looking for! Such a simple solution as it always is with me :)
Answer by Rydrako · Apr 20, 2014 at 11:35 PM
I believe what you want to do is just use a while loop! That way it calls it again when it's done! Also make a new variable and while to check for it and when MouseDown set it to true and on MouseUp make it false!
boolean mouseIsDown;
IEnumator wait()
{
while(mouseIsDown)
{
yield return new WaitForSeconds (0.5f);
bulletSpawnScript.FireBullet ();
callFireBullet();
}
}
void OnMouseDown ()
{
//your code
mouseIsDown = true;
}
void OnMouseUp ()
{
mouseIsDown = false;
}
It should result in the coroutine looping and executing only when the mouse is held down.
I tried this method, and I still had the bullets firing in rapid succession. I ended up going with the first answer provided, that seemed to do what I was looking for! Thanks for the quick response though :)
Answer by $$anonymous$$ · May 30, 2014 at 12:06 AM
ok, I fixed up my code for it to work, monodevelop compiles it. then Unity gives me an error. Assets/dimensionswitcher.cs(6,20): error CS1519: Unexpected symbol =' in class, struct, or interface member declaration this is my new code: using UnityEngine; using System.Collections; public class dimensionswitcher : MonoBehaviour { bool dimension1 = 0; dimension1 = true bool dimension2 = 1; dimension2 = true void Update () { call waitswitch StartCoroutine (waitswitch()); if dimension1 = true { if dimension2 = true {
if (Input.GetKeyDown ("z")) transform.position = new Vector3 (transform.position.x, transform.position.y, dimension1); if (Input.GetKeyDown ("x")) transform.position = new Vector3 (transform.position.x, transform.position.y, dimension2);
} } } } IEnumerator waitswitch(){ dimension1 = false dimension2 = false yield return new WaitForSeconds (3.0f); dimension1 = true dimension2 = true }
Hah, I think you commented on the wrong thread :) But I can tell you your problem. If statements need to use comparison operators and not assignment operators (== vs =). (You are also missing the slashes on your comment.)
//call waitswitch
StartCoroutine (waitswitch());
if (dimension1) {
if (dimension2) {
Because they are booleans you don't need to have any comparison values in the if statement. If's are always asking for true false results. Because you have a boolean you can just go IF (boolean) or IF (!boolean).
Alternatively I believe you can go:
call waitswitch
StartCoroutine (waitswitch());
if (dimension1 == true) {
if (dimension2 == true) {
Also you are missing semi-colons everywhere! (line 6, 8, 23, 24, 26 and 2).
The other problem I see here is you still need to adjust your logic to work correctly. When you call your coroutine you are always setting both dimension variables to true. I don't think this is what you want.
Your answer
![](https://koobas.hobune.stream/wayback/20220613143203im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Play two 2D animation together? 2 Answers
Flipping shot point 2d shooter 1 Answer
2D shooter, 3d or 2d colliders? 2 Answers
2D sidescroller shooting 1 Answer
Instantiate gameobject on random position on 1. a graph and 2. another gameobject 0 Answers