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
1
Question by floydtherooster · Sep 23, 2014 at 07:36 PM · arrayupdategridlevelinstance

2D array values are not updating or pointers are using old instance in Javascript (fixed?)

I have a puzzle game I am creating that features a grid based on the values of a 2D array. The player can then place special orbs that modify the values in the grid squares (0 is a blank orb, 1 is fire orb, 2 is water orb, 3 is lightning orb, 4 is earth orb, 9 is a blank space for an orb to be placed). This works perfectly. The problem I'm having is when I try to reset or change the level, the values are not being reset or properly updated. If I place a special orb in a grid space and change the level, the sprite resets but it retains the special orb value in that position. I'm guessing the issue is with how I'm trying to update the array values for the new level?

Here is my script that is in charge of the array data and the for loops. The GUI button script at the bottom has the current level change code. All of the grid spaces have the "gridspace" tag so they can be deleted before the new level is created.

 //These are variables needed for the level creation portion of the game to work
 var obj_BlankSpot : Transform;
 var obj_PlacedBlankOrb : Transform;
 var currentOrb : int; // sets up the currently selected orb variable for use with other scripts
 static var gridH : int; //used for grid height
 static var gridW : int; //used for grid width
 static var r : int; //used in the grid creation for loops
 static var c : int; //used in the grid creation for loops
 var destroyGrid : GameObject[]; // used to destroy puzzle grid game objects when a level is reset or loaded
  
 //This will create a 2D array that will hold some spots and data for various squares
 //9 represents a blank square where a player can place an orb
 //0 represent a square filled with a blank orb
 var startX : int = -1; // this is the left hand side of the puzzle grid
 var startY : int = 1; // this is the top of the puzzle grid
 var gridArray = [
 [9, 0, 9, 0],
 [9, 9, 0, 9],
 [9, 9, 9, 9],
 [0, 0, 9, 0]];
  
 function Start()
 {
         ///This will end up placing the correct objects in the level based on gridArray
         gridW = gridArray[0].length; //gets the width of the gridArray for the for loops
         gridH = gridArray.length; //gets the height of the gridArray for the for loops
         for(r = 0; r < gridW; r++)
         {
             for(c = 0; c < gridH; c++)
             {
                         var currentX = startX + (r*.96); // this moves newsprites right for each new column being created
                         var currentY = startY - (c*.96); // this moves new sprites down for each new row being created
                         // 1 pixel seems to be .01 unity units. 100 pixels would be 1 unit
                  
                         // r and c are reversed in the if statements so the squares are placed left to right
                         if(gridArray[c][r] == 9)
                 {
                         Instantiate(obj_BlankSpot, Vector3 (currentX, currentY, 0), Quaternion.identity);  //this object is a blank square where a player can place an or
                 }
            
                 else if(gridArray[c][r] == 0)
                 {
                         Instantiate(obj_PlacedBlankOrb, Vector3 (currentX, currentY, 0), Quaternion.identity); // this object is a square that hold a blank orb that can be broken
                 }
                 }
         }
 }
  
 //Make these buttons fully reset the level and not just the graphics of the sprites but all the data as well
 function OnGUI()
 {
     // Make a background box
     GUI.Box (Rect (10,10,100,90), "Menu");
  
     // Make the first button. If it is pressed, the board will be cleared and level 2 will be loaded
     if (GUI.Button (Rect (20,40,80,20), "Level 2"))
     {
    
         destroyGrid =  GameObject.FindGameObjectsWithTag ("gridspace"); // adds all puzzle grid pieces to the destroyGrid array
        
         for(var o = 0 ; o < destroyGrid.length ; o ++) // for all entries in the destroyGrid array
         {
                 Destroy(destroyGrid[o]); //destroys the current grid piece
         }
         // sets up a test grid for level 2
         gridArray = [
         [9, 0, 9, 0, 9],
         [9, 9, 0, 9, 9],
         [9, 0, 9, 0, 9],
         [9, 9, 9, 9, 9],
         [0, 0, 9, 0, 9]];
        
         Start(); // runs the start function again to create the new grid
     }
 }
  

I know that's a chunk of code to sort through, so I took a few screenshots in case those help explain the problem. The first screenshot shows the level 1 4x4 grid with an orb placed in the top left. The second screenshot shows that level 2 has a 5x5 grid but I can't place orbs in the the spot that the lightning orb was placed in level 1 or in the 5th row and column, which weren't present in level 1. That makes me think I'm doing something wrong when I try to update the array for the new level.

alt text alt text

///////////////////////////////////////////////////////////////////////////
////////// UPDATE: Blank Spot Script /////////
///////////////////////////////////////////////////////////////////////////
Here is a copy of the other script in which I modify gridArray from the code above. I cut out a large portion of the code for this example simply to save space since it just consisted of more if statements using the same code. A few things to note is that the gridArrayScript variable links to the script above so that I can access variables from that. xCoord and yCoord in the Awake() function save the r and c values at the time of creation so that each instance of the prefab will remember where it's positioned in the grid. When the game object is clicked on with the mouse, it uses xCoord and yCoord to access its position in gridArray and change the value of that spot. Of course at this point, it looks like the objects are still pulling from the original gridArray instead of the new one in level 2. How would I go about fixing that?

 //selectedOrbScript : scr_gridArray makes it so that I can access scr_gridArray's variables like currentOrb
 //the sprite values make it so that the blank spot can change into various orbs based on what the player has selected
 var gridArrayScript : scr_gridArray;
 gridArrayScript.currentOrb = 0; // sets the value of currentOrb to 0 at the beginning of each level when it is placed
 var xCoord : int;
 var yCoord : int;
 var fireSprite : Sprite;
 var waterSprite : Sprite;
 var lightningSprite : Sprite;
 var earthSprite : Sprite;
  
 function Awake()
 {
         xCoord = gridArrayScript.r; //sets xCoord = to the c value in the loops for the 2D array
         yCoord = gridArrayScript.c; //sets yCoord = to the r value in the loops for the 2D array
 }
  
 /* Orb data codes for if checks in the mouse click function
 0 = blank orb
 1 = fire orb
 11 = fire in empty square
 13 = fire and lightning in empty square
 2 = water orb
 22 = water in empty square
 3 = lightning orb
 33 = lightning in empty square
 4 = earth orb
 9 = empty square
 */
  
 function OnMouseDown ()
 {
         if(gridArrayScript.gridArray[yCoord][xCoord] == 9 ||
            gridArrayScript.gridArray[yCoord][xCoord] == 11 ||
            gridArrayScript.gridArray[yCoord][xCoord] == 13 ||
            gridArrayScript.gridArray[yCoord][xCoord] == 22 ||
            gridArrayScript.gridArray[yCoord][xCoord] == 33) // checks to see if the spot has no orb before executing any code
         {
                 //in the if statements xCoord and yCoord are reversed due to the way the grid is created
                
                 ////////////////////////////////
                 //Fire Orb Code
                 ///////////////////////////////
                 if(gridArrayScript.currentOrb == 1) //execute this is fire orb is currently selected
             {
                         GetComponent(SpriteRenderer).sprite = fireSprite; //changes the sprite to a fire orb
                        
                         if (gridArrayScript.gridArray[yCoord][xCoord] == 33 ||
                             gridArrayScript.gridArray[yCoord][xCoord] == 13 ) // checks to see if the square has lightning or fire and lightning in it
                         {
                                 print ("You broke an orb"); ////////////////// remove this line when testing is done and replace it with a pop up messages, level reset, and broken orb sprite
                         }
                        
                         else //if the spot doesn't have lightning in it to break the fire orb as it's placed, execute the code
                         {      
                                 gridArrayScript.gridArray[yCoord][xCoord] = 1; // changes the data for this square to fire orb
                                
                                 // Executes fire orb code going to the right or x+
                                 if ((xCoord+1) < gridArrayScript.gridW) //checks to see if there is a grid space to the right
                                 {
                                         if (gridArrayScript.gridArray[yCoord][xCoord+1] == 0 ||
                                             gridArrayScript.gridArray[yCoord][xCoord+1] == 3) //checks to see if the object is a blank orb or lightning orb
                                 {
                                         print ("You broke an orb"); ////////////////// remove this line when testing is done and replace it with a pop up messages, level reset, and broken orb sprite
                                 }
                                
                                 else if (gridArrayScript.gridArray[yCoord][xCoord+1] == 9) // checks to see if this is an empty square
                                 {
                                         gridArrayScript.gridArray[yCoord][xCoord+1] = 11; // changes the data for this square to be fire an empty square
                                 }
                                
                                 else if (gridArrayScript.gridArray[yCoord][xCoord+1] == 33) // checks to see if this is an empty square with lightning
                                 {
                                         gridArrayScript.gridArray[yCoord][xCoord+1] = 13; // changes the data for this square to be fire and lightning in an empty square
                                 }
                                
                                 if ((xCoord+2) < gridArrayScript.gridW) //checks to see if there is a grid space 2 spaces to the right
                                 {
                                         if(gridArrayScript.gridArray[yCoord][xCoord+1] != 4) // checks to see if there was an earth orb in the previous square to block this
                                         {
                                                 if (gridArrayScript.gridArray[yCoord][xCoord+2] == 0 ||
                                                         gridArrayScript.gridArray[yCoord][xCoord+2] == 3) //checks to see if the object is a blank orb or lightning orb
                                                 {
                                                         print ("You broke an orb"); ////////////////// remove this line when testing is done and replace it with a pop up messages, level reset, and broken orb sprite
                                                 }
                                                
                                                 else if (gridArrayScript.gridArray[yCoord][xCoord+2] == 9) // checks to see if this is an empty square
                                                 {
                                                         gridArrayScript.gridArray[yCoord][xCoord+2] = 11; // changes the data for this square to be fire an empty square
                                                 }
                                                
                                                 else if (gridArrayScript.gridArray[yCoord][xCoord+2] == 33) // checks to see if this is an empty square with lightning
                                                 {
                                                         gridArrayScript.gridArray[yCoord][xCoord+2] = 13; // changes the data for this square to be fire and lightning in an empty square
                                                 }
                                         }
                                 }
                         }
                 }
         }
           //more similar code for different circumstances     
         }
 }
  

///////////////////////////////////////////////////////////////////////////
/////////////////////////////2ND UPDATE://////////////////////////
///////////////////////////////////////////////////////////////////////////
So I tried out NoseKills debugging process just to double check the values of the array after it had supposedly been updated. As shown above, level 1's array has the following set up:

 [9, 0, 9, 0],
 [9, 9, 0, 9],
 [9, 9, 9, 9],
 [0, 0, 9, 0]];

I placed fire orbs in all of the blank spots which changed it to:

 [1, 0, 1, 0],
 [1, 1, 0, 1],
 [1, 1, 1, 1],
 [0, 0, 1, 0]];

After I press the "level 2 button" the array should be reset to:

 [9, 0, 9, 0, 9],
 [9, 9, 0, 9, 9],
 [9, 0, 9, 0, 9],
 [9, 9, 9, 9, 9],
 [0, 0, 9, 0, 9]];

However it's not changing at all after I used the print out that NoseKills suggested. All of the 9's are still 1's, and the print out isn't even acknowledging that there is a 5th row and column. The highest space on the grid that the printout shows after level 2 was loaded is 3,3 instead of 4,4 like it should be. The second script is still pulling the original array data instead of the new one. Is there any easy to way to fix that or something I should include in my second scripts OnMouseDown or Awake functions?

///////////////////////////////////////////////////////////////////////////
//////////////////////Final Update?//////////////////////////////
///////////////////////////////////////////////////////////////////////////
So I was able to fiddle with things enough that I think I may have stumbled across a fix. From the limited testing that I've done, it looks like the array data is updating properly, even though I'm not 100% sure why this worked and the other did not. With the following code the game starts out with nothing, and pressing the level buttons load the appropriate puzzle grid and wipes away the old data. My only issue at the moment is that I can't declare my 2D array as blank without popping up a bunch of errors in that script or one of the ones that point to it. To bypass that I just threw in a value that has no meaning just to make it work. Here's the new code.

 var startX : int; // used to track the left side of the puzzle grid
 var startY : int; // used to track the top of the puzzle grid
 //this is just a placeholder to declare the 2D array so that there aren't errors, creates a blank level
 static var gridArray = [[99]];
 levelCounter = 0; //starts the level counter at 0
  
 function Start()
 {
         //puts all grid spaces into the destroyGrid array so they can be destroyed before the level is recreated
         destroyGrid =  GameObject.FindGameObjectsWithTag ("gridspace");
     for(var o = 0 ; o < destroyGrid.length ; o ++)//cycles through all the grid spaces
         {
                 Destroy(destroyGrid[o]); //destroys the current grid space
     }
        
         //This will create a 2D array that will hold some spots and data for various squares based on the level
         //9 represents a blank square where a player can place an orb
         //0 represent a square filled with a blank orb
         if(levelCounter == 1) //if level 1 is selected
         {
                 startX = -1; // this is the left hand side of the puzzle grid
                 startY = 1; // this is the top of the puzzle grid
                 gridArray = [
                 [9, 0, 9, 0],
                 [9, 9, 0, 9],
                 [9, 9, 9, 9],
                 [0, 0, 9, 0]]; 
         }
        
         else if(levelCounter == 2) //if level 2 is selected
         {
                 startX = -2; // this is the left hand side of the puzzle grid
                 startY = 1; // this is the top of the puzzle grid
                 gridArray = [
                 [9, 0, 9, 0, 9],
                 [9, 9, 0, 9, 9],
                 [9, 0, 9, 0, 9],
                 [9, 9, 9, 9, 9],
                 [0, 0, 9, 0, 9]];
         }
        
         ///This will end up placing the correct objects in the level based on gridArray
         gridW = gridArray[0].length; //gets the width of the gridArray for the for loops
         gridH = gridArray.length; //gets the height of the gridArray for the for loops
         for(r = 0; r < gridW; r++)
         {
             for(c = 0; c < gridH; c++)
             {
                         var currentX = startX + (r*.96); // this moves newsprites right for each new column being created
                         var currentY = startY - (c*.96); // this moves new sprites down for each new row being created
                         // 1 pixel seems to be .01 unity units. 100 pixels would be 1 unit
                  
                         // r and c are reversed in the if statements so the squares are placed left to right
                         if(gridArray[c][r] == 9)
                 {
                         Instantiate(obj_BlankSpot, Vector3 (currentX, currentY, 0), Quaternion.identity);  //this object is a blank square where a player can place an or
                 }
            
                 else if(gridArray[c][r] == 0)
                 {
                         Instantiate(obj_PlacedBlankOrb, Vector3 (currentX, currentY, 0), Quaternion.identity); // this object is a square that hold a blank orb that can be broken
                 }
                 }
         }
 }

Comment
Add comment · Show 6
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 NoseKills · Sep 24, 2014 at 05:53 AM 0
Share

Do you pass gridArray to some other script to be manipulated by player controls? Do you pass the new grid to that scrip also or is that other script still trying to modify the old grid perhaps? $$anonymous$$ight be useful to put some Debug.Log()s in place to see what actually is stored in the array you are trying to add orbs to in level 2.

avatar image floydtherooster · Sep 24, 2014 at 06:07 AM 0
Share

Actually yeah, the script that I have set up to execute the code for placing orbs into the blank spots ends up accessing gridArray so it can change the value/data of that spot in order to react with the rest of the board.

For example, the blank spot in the top left corner is [0,0] starts with a value of 9 (indicates an empty spot). If I place a fire orb there (value of 1) it would change [0,0] to a value of 1. You're thinking that even those I'm setting the gridArray to have new values, that the old values are still being stored and accessed somewhere? I'll see if I can test that

avatar image NoseKills · Sep 24, 2014 at 06:24 AM 1
Share

Yeah. Could you post code of how you are using gridArray in your other scripts?

You have to realise that when yo make the Level 2 gridArray, that's a completely new array instance. If you passed gridArray to other scripts in Level1, make sure to pass the newly created gridArray to all those scripts in Level 2 again.

avatar image floydtherooster · Sep 24, 2014 at 06:24 PM 0
Share

Alright, i included a portion of the code from the other script that accesses and modifies gridArray. If you have questions about the game mechanics in order for it to make sense, let me know, but it should give you an idea of what I'm doing with gridArray. Would I want to create a variable that represents gridArrayScript.gridArray and have it be set to the new array each time On$$anonymous$$ouseDown is used? Would that make it reference the new instance of the array?

I also did a bit more research last night based on what you said and I came across http://davidwalsh.name/empty-array which explains the "creating a new instance of the array" situation that it looks like I might be having. I did try adding a gridArray.length = 0; line right in the "level 2" button code right before I added the new values to gridArray to see if that helped, but it kept giving me an error saying that .length was read only.

avatar image NoseKills · Sep 24, 2014 at 08:49 PM 1
Share

Based on the new code you posted, it doesn't look like the problem is what i suspected.

I was suspecting a situation like this:

Script 1

         var gridArray = [
         [9, 0, 9, 0],
         [9, 9, 0, 9],
         [9, 9, 9, 9],
         [0, 0, 9, 0]];
         // you pass the gridArray to some other script
         script2.setArray(gridArray);

         // this doesn't update the array we already passed to script 2 
         gridArray = [
         [2, 2, 2, 2],
         [2, 2, 2, 2],
         [2, 2, 2, 2],
         [2, 2, 2, 2]];
         // now the scripts have different arrays
         // gridArrayInScript2 is still full of 0's and 9's and it's a different array than this one


Script 2

 var gridArrayInScript2;
 
 function setArray(var arrayPassedFromScript1)
 {
     gridArrayInScript2 = arrayPassedFromScript1;
 }
 function On$$anonymous$$ouseDown ()
 {
     // do stuff to gridArrayInScript2 ...
 }

 

If you are always accessing gridArray stright gridArrayScript.gridArray there is no way this can happen.

Now my suggestion would be to just add more Debug.Log (or print) to see what's happening. For example to be sure what's in the array you could put this in the beginning of On$$anonymous$$ouseDown()

         for(int r = 0; r < gridArrayScript.gridArray.Length; r++)
         {
             for(int c = 0; c < gridArrayScript.gridArray[r].Length; c++)
             {
                 print("Value at " + r + "," + c + " is " + gridArrayScript.gridArray[r][c]);    
             }
         }
Show more comments

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by floydtherooster · Sep 26, 2014 at 06:18 PM

I may have found a fix for the issue, although I'm not sure why it works and the original method did not. It seems to be working, at least for the testing that I've done so far. I'm going to post my new code above but I don't really want to put it as an answer until I'm 100% sure or understand why it's working.

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

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

A few GUI related questions. 1 Answer

Storing level data from a texture file, and drawing at speed. 0 Answers

How to automatically rearrange a path on a grid ? 0 Answers

Touch and Drag 3D Objects on a Grid (for Android) 0 Answers

Keeping track of array objects 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