Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Krazysh01 · Jun 15, 2014 at 08:13 PM · c#timerlasercooldown

Laser fire time limit

I have a gun that fires a laser but i want to make it so that the laser only remains active for a few seconds and then has to cooldown before it can be used again i have the following code for the laser and the cooldown seems to be working but the problem is that the player can keep the mouse button held down and just perpetually keep on fireing.

 public class LaserScript : MonoBehaviour {
 
     LineRenderer line;
     Light light;
     ParticleSystem particle;
     float cooldown;
     public GameObject explosion;
 
     void Start () {
         line = gameObject.GetComponent<LineRenderer> ();
         light = gameObject.GetComponent<Light>();
         light.enabled = false;
         line.enabled = false;
         cooldown = Time.time;
     }
 
     void Update () {
         if (Input.GetButtonDown ("Fire1")) {
             StopCoroutine("fireLaser");
             StartCoroutine("fireLaser");
         }
     }
 
     IEnumerator fireLaser(){
         light.enabled = true;
         line.enabled = true;
 
         while (Input.GetButton("Fire1") && Time.time >= cooldown) {
             Ray ray = new Ray(transform.position, transform.forward);
             RaycastHit hit;
 
             line.SetPosition(0, ray.origin);
 
             if(Physics.Raycast(ray, out hit, 100)){
                 line.SetPosition(1, hit.point);
                 if(hit.rigidbody){
                     hit.rigidbody.AddForceAtPosition(transform.forward * 5, hit.point);
                     Instantiate (explosion, hit.transform.position, transform.rotation);
                     hit.transform.gameObject.SetActive(false);
                 }
             }
             else{
                 line.SetPosition(1, ray.GetPoint(100));
             }
 
             yield return null;
         }
         line.enabled = false;
         light.enabled = false;
         cooldown = Time.time + 1;
     }
 }

any help you guys can provide id be really gratefull for. thanks in advance.

Comment
Add comment · Show 4
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image supernat · Jun 15, 2014 at 08:21 PM 0
Share

Stopping and starting the laser fire every frame when the mouse button is down is really not efficient, and actually it doesn't work for your requirement. You need to only start the coroutine under the following 2 conditions:

1) The mouse button was not pressed previously

2) The laser is not cooling down

You can stop the coroutine on mouse up or when the cooldingDown flag is turned on. All the coroutine does is show the laser each frame, so you start the coroutine when it is time to show the laser and stop it when it's time to stop showing the laser. The coroutine will increment a heatBuildup value every frame indicating the laser is building up heat.

In Update(), you check heatBuildup for being > some threshold and set the coolingDown flag once reached. Also, you decrement heatbuildup (you may only decrement it when the laser is off if you choose). Lastly, you test heatBuildup for being < some threshold that will shut the coolingDown flag off.

avatar image Krazysh01 supernat · Jun 15, 2014 at 09:44 PM 0
Share

But doesn't get button down only become true for the one frame that it is pressed, regardless of whether it is held down or not?

avatar image supernat supernat · Jun 16, 2014 at 04:57 AM 0
Share

Yes, sorry, I read GetButton from your coroutine, brain melted. You are correct. The rest of the answer still should apply, but I'm going to delete it if I can since I think Bored$$anonymous$$ormon has the better solution.

avatar image Kiwasi · Jun 16, 2014 at 05:56 AM 0
Share

@supernat Your solution was still valid. Ultimately there are two approaches to this problem.

  • @supernat's solution. Only call the laser script if the conditions are true. Check these conditions in update. This is actually the approach I would use. I would also change laser so it is not a coroutine. Then again my personal preference is not to use coroutines at all.

  • $$anonymous$$y solution. Add extra conditions to the coroutine. This will require the $$anonymous$$imum amount of effort to get to from the OP.

Reading this again you could make this faster by caching the result of the raycast. Only worth the effort if you have a lot of these lasers going off everywhere.

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Kiwasi · Jun 15, 2014 at 10:53 PM

In essence there is nothing in your while loop that will trigger the laser to stop firing.

You need a second timer. Try the following at line 27-28. You will also need to throw in a declaration for float FireTimer. Adjust the actual time to suit your needs:

 FireTimer = Time.time + 0.5f;
 while (Input.GetButton("Fire1") && Time.time >= cooldown && Time.time <= FireTimer) 

On a separate note StopCoroutine is not buying you anything, the coroutine will stop itself if the key is released.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Krazysh01 · Jun 16, 2014 at 08:38 AM 0
Share

thanks i just added the stopCoroutine in case anything went wrong and it didn't stop properly. ill try your solution and hopefully it works.

Edit: works perfectly thank you so much for your help.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

How to add a cooldown sort of thing. 1 Answer

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

For loop resetting itself, but needs to stop 2 Answers

Timescale not affect timer? (C#) 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges