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 ajkane · Feb 05, 2015 at 07:35 AM · c#2dlogic

Unity 2D While Loop Problems in simple shoot script (C#)

Hello all,

I am working on top down 2D game. As part of the game's mechanics you will no be able to move while "Drawing" your bow, and we have reduced movement speed for a short time after firing the bow.

I have made two separate scripts. One for most of the logic and the shooting (not actually implemented yet because the logic doesn't work), and one for the player movement which uses two public static bool variables to apply speed multipliers to the movement.

Currently the logic and shooting script has something wrong with the logic that I can't identify. There are a couple print lines in the script and neither of them are ever called.


First Script (ArrowFire.cs):

 using UnityEngine;
 using System.Collections;
 
 public class ArrowFire : MonoBehaviour {
 
     private float BowTimer;
     private float RecoverTimer;
 
     private bool Ready;
 
     public float BowDraw = 0.7f;
     public float Recover = 0.5f;
 
     public static bool Recovering = false;
     public static bool Drawing = false;
 
     // Use this for initialization
     void Start () 
     {
         Ready = true;    
     }
 
     void OnLevelWasLoaded ()
     {
         Ready = true;
         Bow();
     }
 
 
     void Bow () {
         while (true)
         {
             while (Input.GetKeyDown (KeyCode.Space) && Ready)
             {
                 Drawing = true;
                 BowTimer += Time.deltaTime;
 
                 if (BowTimer >= BowDraw)
                 {
 
                     //insert projectile fire code here
                     print ("bam");
 
                     Ready = false;
                 }
             }
 
             while (!Ready)
             {
                 BowTimer = 0.0f;
                 Drawing = false;
                 Recovering = true;
 
                 RecoverTimer += Time.deltaTime;
 
                 if (RecoverTimer > Recover)
                 {
                     print ("recovering");
                     Ready = true;
                     Recovering = false;
                 }
     
             }
             RecoverTimer = 0.0f;
         }
     
     }
 }
 



Second Script (PlayerMove.cs)

 using UnityEngine;
 using System.Collections;
 
 
 public class PlayerMove : MonoBehaviour {
     //define public variable for speed control
     public float setmulti; //set speed multiplyer in engine
     public float multidiag; //diaganal speed multiplier (should be less than 1.0f)
 
     private float multi; //internal speed multiplier
  
     private Vector2 vectmove; //make new Vector2 for velocity control
 
     private float recovermulti = .5f; //speed multiplier when recovering from bow shot
 
     public static bool Recovering; //shared variable recovering from bow shot
     public static bool Drawing; //share variable currently drawing bow
 
 
     // Update is called once per frame
     void Update () {
         //Upate Drawing and Recovering status from Arrow Fire script
         Recovering = ArrowFire.Recovering;
         Drawing = ArrowFire.Drawing;
 
         //Check key status
         float horz = Input.GetAxis("Horizontal"); //set horz to equal the value of the horizontal axis
         float vertz = Input.GetAxis("Vertical"); //set vertz to equal the value of the vertical axis
 
 
 
         //internal multi multipliers
         if (Drawing) //When drawing bow
         {
             multi = 0.0f; //set speed multiplier to 0 (no movement)
 
         }
         else if (Recovering) //When recovering from bow shot
         {
             multi = setmulti * recovermulti; //set internal speed multiplier to speed multiplier specified in engine times the recovering speed multiplier specified in engine
         }
         else
         {
             multi = setmulti; //set internal speed multiplier to speed mulitplier specified in engine
         }
 
 
 
 
         if (horz > 0 && vertz == 0) //if not diagnal movement
         {
             vectmove = new Vector2 (horz * multi, vertz * multi); //multiply vertical and horizontal speed by multiplyer and apply movement to player
         }
         else if (horz == 0 && vertz > 0) //if not diagnal movement
         {
             vectmove = new Vector2 (horz * multi, vertz * multi); //multiply vertical and horizontal speed by multiplyer and apply movement to player
         }
         else if (horz == 0 && vertz < 0) //if not diagnal movement
         {
             vectmove = new Vector2 (horz * multi, vertz * multi); //multiply vertical and horizontal speed by multiplyer and apply movement to player
         }
         else if (horz < 0 && vertz == 0) //if not diagnal movement
         {
             vectmove = new Vector2 (horz * multi, vertz * multi); //multiply vertical and horizontal speed by multiplyer and apply movement to player
         }
         else
         {
             vectmove = new Vector2 ((horz * multi)*multidiag, (vertz * multi))*multidiag; //multiply vertical and horizontal speed by multiplyer AND DIAGNAL MOVEMENT MULTIPLYER and apply movement to player
 
         }
 
 
         //Move player
         rigidbody2D.velocity = vectmove;
 
 
 
 
     }
 }



Comment
Add comment · Show 1
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 sysameca · Feb 05, 2015 at 08:50 AM 0
Share

The while loops you define does not work like you think they will do. Inside a non updating function the while loop is running just one frame. First, I'd say get rid of those while loops and place that bow logic inside the Update(). Second those static variables are just calling for trouble. Those globally shared variables need to be inside a custom manager defined as a singleton.

1 Reply

· Add your reply
  • Sort: 
avatar image
2

Answer by daneislazy · Feb 05, 2015 at 12:47 PM

Yes, as sysameca says, while does not work like that. while loops are just logic loops like For loops. They can just keep looping and not allow the rest of your code to work. You are probably thinking they will run in parallel with the rest of the code, this is not the case. For something like that you can use Coroutines. But in this case you don't need those either.

Also it's worth noting that OnLevelWasLoaded() only fires when a new scene is loaded from the current one. It won't do anything if you are not switching scenes.

So to fix it change the OnLevelWasLoaded() to Update() and remove the ready = true; you can add an if check in front of the Bow() call if you would like to enable/disable it. Then in Bow() remove the first while and change the other two to If statements, and move the RecoverTimer = 0.0f; to inside the if (RecoverTimer > Recover). Finally, the Input.GetKeyDown only fires Once when the key is pressed; use Input.GetKey to check the state of the key.

This should make the whole Bow() method be run through once per frame and should make it work.

Comment
Add comment · Show 5 · 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 ajkane · Feb 05, 2015 at 10:26 PM 0
Share

daneislazy,

Thanks for your quick reply. I tried to implement the changes that you suggested, but I was unable to get the script the run successfully.

Here is the new version of the ArrowFire.cs:

 using UnityEngine;
 using System.Collections;
 
 public class ArrowFire : $$anonymous$$onoBehaviour {
 
     private float BowTimer;
     private float RecoverTimer;
 
     private bool Ready;
 
     public float BowDraw = 0.7f;
     public float Recover = 0.5f;
 
     public static bool Recovering = false;
     public static bool Drawing = false;
 
     // Use this for initialization
     void Start () 
     {
         Ready = true;    
     }
 
     void Update ()
     {
         Bow();
     }
 
 
     void Bow () {
         if (Input.Get$$anonymous$$ey ($$anonymous$$eyCode.Space) && Ready)
         {
             Drawing = true;
             BowTimer += Time.deltaTime;
 
             if (BowTimer >= BowDraw)
             {
 
                 //insert projectile fire code here
                 print ("bam");
 
                 Ready = false;
                 BowTimer = 0.0f;
             }
         }
 
         if (!Ready)
         {
             Drawing = false;
             Recovering = true;
 
             RecoverTimer += Time.deltaTime;
 
             if (RecoverTimer > Recover)
             {
                 print ("recovering");
                 Ready = true;
                 Recovering = false;
                 RecoverTimer = 0.0f;
             }
     
         }
     
     }
 }
avatar image sysameca · Feb 06, 2015 at 08:03 AM 0
Share

And what exactly is the problem here? It seems like the script should work now.When you hold space it will wait for the recover time and will shoot your arrow. Then the script will wait the bow timer to run out and then will shoot another arrow. And that process will repeat until holding space. Isn't this what are you trying to achieve. Please do a little bit of explanation when you say that something doesn't work right.

avatar image ajkane · Feb 06, 2015 at 08:10 AM 0
Share

That is exactly what I'm trying to achieve. The print "bam" is never called when I hold down space. Nothing shows up in the console at all.

avatar image sysameca · Feb 06, 2015 at 08:28 AM 0
Share

Hm. I just pasted the code and it prints out "bam". $$anonymous$$aybe you forgot to place the script inside a game object?

avatar image ajkane · Feb 06, 2015 at 08:37 AM 0
Share

Alright, I'll try to figure it out tomorrow. I don know the script is in the game object though. Thank you for all of 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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Button Enabling/Disabling using Collision Triggers? 1 Answer

2D platformer- getting errors I don't understand (c#) 1 Answer

How to make Comanion AI pass through the player??,How to make your Companion AI pass through the player?? 0 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