Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 JamieRoss95 · Jun 17, 2019 at 04:58 PM · lerpcoroutinesfor-loopwhile-loop

Can't figure out While Loop crash?

I am creating a turn-based grid combat system for my dungeon crawler and have run into an issue with the enemy turns. Each enemy has "x" amount of total ap, they use it each time they move. I have created a While(enemy.apCur > 0) loop but for some reason, it crashes/freezes the game. I have tried running it without the while loop and the movement properly subtracts 1ap when the enemy moves, but for some reason, there is a crash somewhere along the way when it is in a while loop. The reason I want to do this in a while loop is because I want the current enemy to exhaust all of its AP before moving onto the next enemy's turn... currently, all the enemies take their turns in unison without the While loop.

There is a bunch of systems working within my scripts so I will try and cut out the info that is unnecessary within the scripts for ease of readability. First, my combat manager's ChooseNextInLine() function is called to choose the next enemy/player in the turn order (which is determined when the combat is initiated):

 public void ChooseNextInLine()
 {
     GameObject curEntity = _turnOrder.Dequeue();
 
     if (curEntity.GetComponent<PlayerManager>() != null) //PLAYER
     {
         _turnOrder.Enqueue(curEntity);
         PlayerCombatTurn();
     }
     else if (curEntity.GetComponent<ClassEnemy>() != null) //ENEMY
     {
         ClassEnemy curEnemy = curEntity.GetComponent<ClassEnemy>();
 
         _turnOrder.Enqueue(curEntity);
         EnemyCombatTurn(curEnemy);
     }
 }

The enemy combat is then called:

         enemy.apCur = enemy.apMax;
 
         while (enemy.apCur > 0)
         {
             if (!enemy.isMoving)
             {
                 enemy.apCur--;
 
                 bool tileSelected = false;
                 Vector3[] possibleTiles = enemy.surroundingTiles.ToArray();
 
                 //RANDOMIZE THE ARRAY ORDER
                 for (int q = 0; q < enemy.surroundingTiles.Count; q++)
                 {
                     int rand = RandomNumberGenerator.Instance.rndCombat.Next(enemy.surroundingTiles.Count);
                     Vector3 temp = possibleTiles[rand];
 
                     possibleTiles[rand] = possibleTiles[q];
                     possibleTiles[q] = temp;
 
                 }
                 //LOOK FOR A TILE TO MOVE TO
                 foreach (Vector3 tile in possibleTiles)
                 {
                     if (!combatOccupiedTiles.Contains(tile) && combatActiveTiles.Contains(tile))
                     {
                         tileSelected = true;
 
                         enemy.targetPos = tile;
 
                         enemy.MovingTurn();
                         break;
                     }
                 }
 
                 if (!tileSelected)
                 {
                     print("No tile selected");
                 }
             }
         }
         enemy.isMoving = false; //Failsafe bool assignment
         ChooseNextInLine();

The enemy.MovingTurn() function runs a coroutine that Lerps the enemy from its current position to the targetPos. At the beginning of the coroutine enemy.isMoving is set to true, and at the end it is set to false. I believe it is somewhere in here that there is an issue, but I can't figure out where. Here is the appropriate script:

 public IEnumerator MoveToPosition(Vector3 targetPos)
     {
         float time = 0f; //Reset timer
         _parentEnemy.isMoving = true;
 
         //MOVE THE PLAYER
         while (time < 1)
         {
             time += Time.deltaTime / (GameManager.Instance.enemyTurnTime); //How much time has passed relatively 
             transform.position = Vector3.Lerp(curPos, targetPos, time);
             yield return null;
         }
 
         transform.position = targetPos;
         AddSurroundingTiles();
     }
 
     public void AddSurroundingTiles()
     {
         //SET VECTORS
         curPos = transform.position;
         _parentEnemy.curPos = curPos;
 
         _parentEnemy.surroundingTiles.Clear();
 
         //FIND NEW SURROUNDING TILES
         _parentEnemy.surroundingTiles.Add(new Vector3(curPos.x, curPos.y + 1, curPos.z)); //UP
         _parentEnemy.surroundingTiles.Add(new Vector3(curPos.x, curPos.y - 1, curPos.z)); //DOWN
         _parentEnemy.surroundingTiles.Add(new Vector3(curPos.x + 1, curPos.y, curPos.z)); //RIGHT
         _parentEnemy.surroundingTiles.Add(new Vector3(curPos.x - 1, curPos.y, curPos.z)); //LEFT
 
         _parentEnemy.isMoving = false;
     }

Any help would be greatly appreciated, thanks!

Comment
Add comment
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

1 Reply

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

Answer by SirPaddow · Jun 17, 2019 at 05:41 PM

Your while is actually locking the current frame because it will only end once the ap is 0 (but it will not happen in the current frame). Coroutines only play once per frame too, so your "MoveToPosition" function will never continue after the first time it "yield return"s. To fix it you need to move your while in a coroutine too, and let it go as long as the enemy is moving, something like this:

 public void ChooseNextInLine()
 {
 
     // player stuff ...
 
     // if enemy
     ClassEnemy curEnemy = curEntity.GetComponent<ClassEnemy>();
     _turnOrder.Enqueue(curEntity);
     StartCoroutine(EnemyCombatTurn(curEnemy));
 }
 
 public IEnumerator EnemyCombatTurn(ClassEnemy enemy)
 {
     enemy.apCur = enemy.apMax;
     while (enemy.apCur > 0)
     {
         enemy.apCur--;
         // Get the tile and start moving there
 
         while (enemy.isMoving)
         {
             yield return null; // < here we let the game loop go to the next frame
         }
     }
     enemy.isMoving = false; //Failsafe bool assignment
     ChooseNextInLine();
 }
 
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 JamieRoss95 · Jun 17, 2019 at 05:59 PM 0
Share

I see that clears it up a bunch! Thanks for the answer and the explanation.

Cheers!

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

109 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Time.time undependable in a coroutine? 1 Answer

for/while loops not working, or not updating 1 Answer

Lerp returning max value halfway 1 Answer

How to spawn evenly spaced game objects and move them in a circular path? 1 Answer

How to start a coroutine with WaitForSeconds on key down? 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