Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
2
Question by Afoo · Aug 31, 2014 at 06:23 PM · c#freeze

Unity freezes on play

Hey, I'm starting to play with Unity, I want to rewrite a simple TD game I made in Java. Unfortunately very fast I bumped on a problem. When I click play my Unity freezes, I have to kill a task. I have no idea what's wrong, I tried some Debug.Logs but I can't even view them, can't access unity after the play button. I searched my code for infinite loops and I can't find any (being able to see console logs would help).

So far the code only has 3 classes, here's the first simple one to hold the static variables:

 public class GlobalVariables : MonoBehaviour {
 
     //The width of the board in blocks
     public static int boardWidth = 40;
 
     //The height of the board in blocks
     public static int boardHeight = 36;
 
     //The lenghth of the road in blocks;
     public static int pathLength = 30;
 
     //Pixel size of a block
     public static int blockSize = 64;
 
     void Start () {
     }
     void Update () {
     }
 }


Second class prepares a matrix, which I use for drawing:

 public class MapCreator
 {
 
         //Array containing the path 
         int[] directionLayout = new int[GlobalVariables.pathLength];
 
         public int[] getDirectionLayout ()
         {
                 return directionLayout;
         }
 
         public MapCreator() {}
         
         /**
         *Returns an index layout of game board.
         */
         public int[,] prepareMap ()
         {
         
                 //X and Y position of start and end
                 int startValueX;
                 int startValueY;
         
                 //Used while creating a path
                 int tempValueX;
                 int tempValueY;
                 int xDirection;
                 int yDirection;
                 int pathRemaining = GlobalVariables.pathLength;
         
                 //Used for random
                 int[] randomDirection = {-1, 1};
         
                 //Return matrix
                 int[,] mapIndexLayout = new int[GlobalVariables.boardWidth, GlobalVariables.boardHeight];
         
                 for (int i = 0; i < GlobalVariables.boardWidth; i++) {
                         for (int k = 0; k < GlobalVariables.boardHeight; k++) {
                                 mapIndexLayout [i, k] = 0;
                                 Debug.Log("Filling with 0, step: " + i + ", " + k);
                         }
                 }
         
                 startValueX = Random.Range (1, GlobalVariables.boardWidth - 2);
                 startValueY = Random.Range (1, GlobalVariables.boardHeight - 2);
                 tempValueX = startValueX;
                 tempValueY = startValueY;
         
                 mapIndexLayout [startValueX, startValueY] = 2;
         
                 while (pathRemaining > 0) {    
                         xDirection = randomDirection [Random.Range (0, 2)];
                         if (xDirection == 1) {
                                 yDirection = -1;
                         } else {
                                 yDirection = 1;
                         }
             
                         if (1 < (tempValueX + xDirection) && (tempValueX + xDirection) < (GlobalVariables.boardWidth - 2) 
                                 && 1 < (tempValueY + yDirection) && (tempValueY + yDirection) < (GlobalVariables.boardHeight - 2)) {
                                 if (mapIndexLayout [tempValueX + xDirection, tempValueY + yDirection] == 0) {
                                         if (pathRemaining > 1) {
                                                 mapIndexLayout [tempValueX + xDirection, tempValueY + yDirection] = 1;
                                         } else {
                                                 mapIndexLayout [tempValueX + xDirection, tempValueY + yDirection] = 3;
                                         }
 
                                         if (xDirection == 0 && yDirection == 1) {
                                                 directionLayout [40 - pathRemaining] = 8;
                                         } else if (xDirection == 0 && yDirection == -1) {
                                                 directionLayout [40 - pathRemaining] = 2;
                                         } else if (xDirection == 1 && yDirection == 0) {
                                                 directionLayout [40 - pathRemaining] = 6;
                                         } else if (xDirection == -1 && yDirection == 0) {
                                                 directionLayout [40 - pathRemaining] = 4;
                                         } 
 
                                         pathRemaining -= 1;
                     
                                         tempValueX += xDirection;
                                         tempValueY += yDirection;
                                 }
                         }
                         Debug.Log("Creating path, remains: " + pathRemaining + " blocks.");
                 }
                 
                 Debug.Log("Path Created");
 
                 return mapIndexLayout;
         }
 
         // Use this for initialization
         void Start ()
         {
     
         }
     
         // Update is called once per frame
         void Update ()
         {
     
         }
 }

The last class takes the matrix and draws tiles based on it (well, it does not, but that's my goal :P)

 public class MapDrawer : MonoBehaviour
 {
         //Object containing prepareMap method
         MapCreator mapCreator = new MapCreator ();
 
         //Textures has to be chosen in inspector 
         public Texture grassTexture;
         public Texture roadTexture;
         public Texture startTexture;
         public Texture endTexture;
 
         //Temporary texture
 
 
         /**
          * Method drawing a board
          */
         void drawMap ()
         {
 
             Debug.Log("Begin drawing the map.");
 
             //Index layout of game board
             int[,] mapIndexLayout = mapCreator.prepareMap ();
             
             //Temporary texture
             Texture tempTexture;
 
             if (!grassTexture && !roadTexture && !startTexture && !endTexture) {
                 Debug.LogError ("Assign Textures in the inspector.");
                 return;
             }
             
             for (int i = 0; i < GlobalVariables.boardWidth; i++) {
                 for (int k = 0; k < GlobalVariables.boardHeight; k++) {
                     tempTexture = setTextureById(mapIndexLayout[i, k]);
                     Debug.Log("Drawing at position: " + i + ", " + k);
                     GUI.DrawTexture (new Rect ((i * GlobalVariables.blockSize), (k * GlobalVariables.blockSize), GlobalVariables.blockSize, GlobalVariables.blockSize), tempTexture, ScaleMode.ScaleToFit, true, 0);
                 }
             }
         }
 
         Texture setTextureById(int id) {
             
             Debug.Log("Setting texture");
 
             if (id == 0) {
                 return grassTexture;
             } else if (id == 1) {
                 return roadTexture;
             } else if (id == 2) {
                 return startTexture;
             } else if (id == 3) {
                 return endTexture;
             }
             
             return null;
         }
 
         // Use this for initialization
         void Start ()
         {
             drawMap ();
         }
     
         // Update is called once per frame
         void Update ()
         {
     
         }
 }


I would be grateful for any help. By the way, leaving the unity untouched doesn't help, but I noticed that memory usage keeps rising, slowly but steady, from ~~150000k to ~~700000k when I killed the task.

Comment
Add comment · Show 2
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 Afoo · Sep 03, 2014 at 05:18 PM 0
Share

Seems I had some terrible wrong logic behind direction select. Sorry for your time.

avatar image kacyesp · Sep 03, 2014 at 06:06 PM 1
Share

So you did you have an infinite loop :) By the way, when people ask questions on here, they're supposed to vote up anything that helped them (answers or comments) and/or accept an answer if it answered their question.

2 Replies

· Add your reply
  • Sort: 
avatar image
2

Answer by kacyesp · Aug 31, 2014 at 10:30 PM

You have an infinite loop: while ( pathRemaining > 0 )

You only decrement pathRemaining when both of these if statements are true:

   if (1 < (tempValueX + xDirection) && (tempValueX + xDirection) < (GlobalVariables.boardWidth - 2) 
                                     && 1 < (tempValueY + yDirection) && (tempValueY + yDirection) < (GlobalVariables.boardHeight - 2)) {

   if (mapIndexLayout [tempValueX + xDirection, tempValueY + yDirection] == 0)


Step through your code with a debugger or use Debug.Break() to pause the execution and see your Debug.Log statements in the console.

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 Kiwasi · Sep 01, 2014 at 12:33 AM 1
Share

Pretty much the only time Unity freezes up is an infinite while loop. In every other case there will be an error.

One possible solution is to count iterations through your loop and abort if a set number is reached.

avatar image kacyesp · Sep 01, 2014 at 12:55 AM 1
Share

@Bored$$anonymous$$ormon I have 2 loops in my own code that were infinite in a few corner cases, and even after fixing them, I still leave a counter in there that breaks out after it hits 3 with a little comment saying "//Safety net" :)

avatar image Afoo · Sep 01, 2014 at 04:21 AM 0
Share

Thanks for your help but I don't see an infinite loop there, the logic behind this if statement is: if tempValueX is in range from 1 to width -2, same for tempValueY, and then check if the Id on the matrix is 0 (which stands for grass, I fill the table with zeros in the begining). Even tho it might indeed take a long while I should, sooner or later, finish. I will look for Debug.Break() today when I come back from work.

avatar image Kiwasi · Sep 01, 2014 at 06:04 AM 1
Share

@Afoo It doesn't really matter if you see the infinite loop or not. Unity can see it.

avatar image Kiwasi · Sep 01, 2014 at 06:14 AM 1
Share
 if (1 < (tempValueX + xDirection) && (tempValueX + xDirection) < (GlobalVariables.boardWidth - 2) && 1 < (tempValueY + yDirection) && (tempValueY + yDirection) < (GlobalVariables.boardHeight - 2)) {
     if (mapIndexLayout [tempValueX + xDirection, tempValueY + yDirection] == 0) {
                      

Both of these ugly if statements must return true for your loop to ter$$anonymous$$ate. $$anonymous$$y first suggestion would be to refractor these into something readable.

An alternative way to debug this would be to convert it into a coroutine, and yield return null immediately inside the while loop. Then you can watch the progress in real time.

avatar image
0

Answer by AlwaysSunny · Aug 31, 2014 at 10:21 PM

Several things stand out:
GlobalVariables class doesn't need to inherit from MonoBehavior, and should be static.
GUI.DrawTexture, like any GUI.something call, must be called from built-in OnGUI(){} method.
GUI.DrawTexture is not a valid way to draw this many objects.
GUI.anything only works on the frame it was called, so calling outside a loop is generally useless.
Your best bet for creating a tile map is probably instantiating one quad per tile whose UVs match the desired texture on a texture atlas, then combining those quads into a single mesh to reduce draw calls from 100s to just 1.
Debug.Log lines can cause huge slowdowns. You should never have an instance where 100s of them can be made in the same frame. That might be your crash problem.

I didn't really dig into the code to look for specific errors beyond these, but these points need to be addressed.

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 Afoo · Sep 01, 2014 at 04:15 AM 0
Share

Thanks, will look for these changes when I come back from work today.

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

Player movement issue... 1 Answer

Unity Freeze When Applying my Script to GameObject 3 Answers

Clamping a Manipulated Camera 0 Answers

Changing values of a script from another script not showing in game 1 Answer

How may I get the children (direct and dependents) of a game object? 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