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 RNVitter · Jul 24, 2014 at 03:32 AM · arrayrandomgridshuffle

Randomly Choosing two objects from an array and switching their positions

I have a 6x9 grid of tiles, I want it so every 2-5 seconds two random tiles switch positions, I have the array set up and the invokerepear method but I do not know how to randomly select two objects from the array in the grid and switch their positions.

This is what I have far

 public GameObject _indicator;//The indicator to know the selected tile
     public GameObject[,]  _arrayOfShapes;//The main array that contain all games tiles
     private GameObject _currentIndicator;//The current indicator to replace and destroy each time the player change the selection
     private GameObject _FirstObject;//The first object selected
     private GameObject _SecondObject;//The second object selected
     public GameObject [] _listOfGems;//The list of tiles we can see in the game 
     public int _gridWidth;//the grid number of cell horizontally
     public int _gridHeight;//the grid number of cell vertically
    
     // Use this for initialization
     void Start () {
         //Initializing the array with _gridWidth and _gridHeight passed in parameter
         _arrayOfShapes = new GameObject[_gridWidth, _gridHeight];
         //Creating the gems from the list of gems passed in parameter
         for ( int i = 0; i <= _gridWidth-1; i++){
             for ( int j = 0; j <= _gridHeight-1; j++){
                 var gameObject = GameObject.Instantiate(_listOfGems[Random.Range(0, _listOfGems.Length)] as GameObject, new Vector3(i, j, 0), transform.rotation) as GameObject;
                 _arrayOfShapes[i,j]= gameObject;
          }
         }
         //Adding the star effect to the gems and call the DoShapeEffect continuously
    InvokeRepeating("DoShapeEffect", 1f, 0.21F);
     }
         
     void Shuffle ()
     {
 
     }
 
     // Update is called once per frame
     void Update () {
 
         InvokeRepeating ("Shuffle", 2, Random.Range(2,5));

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 sethuraj · Jul 24, 2014 at 06:50 AM 0
Share

By switching position,do you mean to switch the transform.position of the object in the array to each other or the location of the object in the array...?

3 Replies

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

Answer by calebheale · Jul 24, 2014 at 06:50 AM

// to pick random elements

 int x1, y1, x2, y2;
         
 x1 = Random.Range(0, _arrayOfShapes.GetLength(0));
 x2 = Random.Range(0, _arrayOfShapes.GetLength(0));
 y1 = Random.Range(0, _arrayOfShapes.GetLength(1));
 y2 = Random.Range(0, _arrayOfShapes.GetLength(1));
     

// to swap array positions

 GameObject temp = _arrayOfShapes[x1, y1];
 _arrayOfShapes[x1, y1] = _arrayOfShapes[x2, y2];
 _arrayOfShapes[x2, y2] = temp;

// OR to swap physical locations

 Vector3 temp = _arrayOfShapes[x1, y1].transform.position;
 _arrayOfShapes[x1, y1].transform.position = _arrayOfShapes[x2, y2].transform.position;
 _arrayOfShapes[x2, y2].transform.position = temp;










Comment
Add comment · Show 6 · 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 calebheale · Jul 24, 2014 at 06:57 AM 0
Share

$$anonymous$$eep in $$anonymous$$d that this has a possibility of choosing the same element for both. This shouldn't cause any exceptions or other issues other than the fact that every once in a while it will just appear that nothing switched. If you want to insure that it will never pick the same element you could do:

 int x1, y1, x2, y2;
  
 x1 = Random.Range(0, _arrayOfShapes.GetLength(0));
 y1 = Random.Range(0, _arrayOfShapes.GetLength(1));
 
 do { 
    x2 = Random.Range(0, _arrayOfShapes.GetLength(0));   
    y2 = Random.Range(0, _arrayOfShapes.GetLength(1));
 } while(x1 == x2 && y1 == y2);

Both are valid solutions. Just depends on exactly what functionality you are going for.

avatar image RNVitter · Jul 24, 2014 at 11:54 PM 0
Share

So the tiles now randomly switch however, my game is a $$anonymous$$atch-3 game, so while it looks like the tiles swap positions they don't actually swap positions, it still thinks that the tile is in its original position, is there a way to fix this? I've been looking over my entire script and I can't think of a way to fix

avatar image calebheale · Jul 25, 2014 at 02:04 AM 0
Share

If you are checking for matches by iterating through the array you may need to use both the swap for the positions in the array AND the physical positions. Is that what you are doing? If that doesn't help you please post some code.

avatar image RNVitter · Jul 25, 2014 at 04:20 AM 0
Share

I thought to do that but was not sure how exactly to combine them together and I posted some more code in another comment due the character limit and thanks for all the help again!

avatar image RNVitter · Jul 25, 2014 at 04:22 AM 0
Share

i also get this error while I'm playing the game

The object of type 'GameObject' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object.

Show more comments
avatar image
0

Answer by smallbit · Jul 24, 2014 at 06:50 AM

Little code like this, not tested but should work:

  void Shuffle()
     {
         //get random coordinates for both elements 
         int x1 = Random.Range(0,_arrayOfShapes.GetLength(0)-1);
         int y1 = Random.Range(0,_arrayOfShapes.GetLength(1)-1);
         int x2 = Random.Range(0,_arrayOfShapes.GetLength(0)-1);
         int y2 = Random.Range(0,_arrayOfShapes.GetLength(1)-1);
 
         //if by any luck the point to the same element start over
         if(_arrayOfShapes[x1,y1] == _arrayOfShapes[x2,y2])
         {
         Shuffle();
         }
         else
         {
             //if they are different swap
             //create tmp gameobject and save first element there
             GameObject tmp = _arrayOfShapes[x1,y1];
             //replace first element by seconds 
             _arrayOfShapes[x1,y1] = _arrayOfShapes[x2,y2];
             //copy first elemtn tmp to second
             _arrayOfShapes[x2,y2] = tmp;
         }
 
       
     }    // Update is called once per fr


If you want to swap (move the gameobjects) you might do something like this

  //if they are different swap
             //create tmp gameobject and save first element there
           Vector3 tmp = _arrayOfShapes[x1,y1].transform.position;
             //replace first element by seconds 
             _arrayOfShapes[x1,y1].transform.position = _arrayOfShapes[x2,y2].transform.position;
             //copy first elemtn tmp to second
             _arrayOfShapes[x2,y2].transform.position = tmp;



Comment
Add comment · Show 3 · 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 calebheale · Jul 24, 2014 at 07:12 AM 1
Share

Wow. We posted almost the exact same solution at almost the exact same time... eerie.

avatar image calebheale · Jul 24, 2014 at 07:16 AM 0
Share

Also, I don't think you want the (-1)'s on the range because the upper bounds is already exclusive.

avatar image RNVitter · Jul 24, 2014 at 05:59 PM 0
Share

all your guys answers worked great thanks!! wish I could pick all of them

avatar image
0

Answer by RNVitter · Jul 25, 2014 at 04:47 AM

Here is the next part of the code after the part I've already posted

 void Shuffle ()
     {
         x1 = Random.Range(0, _arrayOfShapes.GetLength(0));
         x2 = Random.Range(0, _arrayOfShapes.GetLength(0));
         y1 = Random.Range(0, _arrayOfShapes.GetLength(1));
         y2 = Random.Range(0, _arrayOfShapes.GetLength(1));
 
         Vector3 temp = _arrayOfShapes[x1, y1].transform.position;
         _arrayOfShapes[x1, y1].transform.position = _arrayOfShapes[x2, y2].transform.position;
         _arrayOfShapes[x2, y2].transform.position = temp;
     }
 
     // Update is called once per frame
     void Update () {
         
         bool shouldTransit = false;
         //Detecting if the player clicked on the left mouse button and also if there is no animation playing
         if (Input.GetButtonDown ("Fire1") && HOTween.GetTweenInfos()==null) {
            
             Destroy(_currentIndicator);
             //The 3 following lines is to get the clicked GameObject and getting the RaycastHit2D that will help us know the clicked object
             Ray ray   = Camera.main.ScreenPointToRay (Input.mousePosition);
             RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
             if (hit.transform!=null)
             {  //To know if the user already selected a tile or not yet
                if ( _FirstObject == null ) _FirstObject = hit.transform.gameObject;
                else {_SecondObject=  hit.transform.gameObject;
                     shouldTransit= true ; }
 
                 _currentIndicator =  GameObject.Instantiate (_indicator,new Vector3( hit.transform.gameObject.transform.position.x,hit.transform.gameObject.transform.position.y,-1), transform.rotation) as GameObject ;
                 //If the user select the second tile we will swap the two tile and animate them
                 if (shouldTransit)
                 {
                     //Getting the position between the 2 tiles
                     var distance = _FirstObject.transform.position - _SecondObject.transform.position;
                     //Testing if the 2 tiles are next to each others otherwise we will not swap them 
                     if (Mathf.Abs(distance.x) <= 1 && Mathf.Abs(distance.y) <= 1)
                     {   //If we dont want the player to swap diagonally
                         if (!_canTransitDiagonally  )
                         {
                             if (distance.x != 0 && distance.y != 0)
                             {
                                 Destroy(_currentIndicator); 
                                 _FirstObject = null;
                                 _SecondObject = null; 
                                 return;
                             }
                         }
                        //Animate the transition
                         DoSwapMotion(_FirstObject.transform, _SecondObject.transform);
                         //Swap the object in array
                         DoSwapTile(_FirstObject, _SecondObject, ref _arrayOfShapes);
 
                                                 
                     }
                     else
                     {
                         _FirstObject = null;
                         _SecondObject = null;
 
                     }
                    Destroy(_currentIndicator);
                                        
                 }
                
             }
           
         }
     }
 
     // Find Match-3 Tile
     private ArrayList FindMatch(GameObject[,] cells)
     {//creating an arraylist to store the matching tiles
         ArrayList stack = new ArrayList();
         //Checking the vertical tiles
         for (var x = 0; x <= cells.GetUpperBound(0); x++)
         {
             for (var y = 0; y <= cells.GetUpperBound(1); y++)
             {
                 var thiscell = cells[x, y];
                 //If it's an empty tile continue
                 if (thiscell.name == "Empty(Clone)") continue;
                 int matchCount = 0;
                 int y2 = cells.GetUpperBound(1);
                 int y1;
                 //Getting the number of tiles of the same kind
                 for (y1 = y + 1; y1 <= y2; y1++)
                 {
                    if (cells[x, y1].name == "Empty(Clone)" || thiscell.name != cells[x, y1].name) break;
                     matchCount++;
                 }
                 //If we found more than 2 tiles close we add them in the array of matching tiles
                 if (matchCount >= 2)
                 {
                     y1 = Mathf.Min(cells.GetUpperBound(1) , y1 - 1);
                     for (var y3 = y; y3 <= y1; y3++)
                     {
                         if (!stack.Contains(cells[x, y3]))
                         {
                             stack.Add(cells[x, y3]);
                         }
                     }
                 }
             }
         }
         //Checking the horizontal tiles , in the following loops we will use the same concept as the previous ones
         for (var y = 0; y < cells.GetUpperBound(1) + 1; y++)
         {
             for (var x = 0; x < cells.GetUpperBound(0) + 1; x++)
             {
                 var thiscell = cells[x, y];
                 if (thiscell.name == "Empty(Clone)") continue;
                 int matchCount = 0;
                int x2 = cells.GetUpperBound(0);
                 int x1;
                 for (x1 = x + 1; x1 <= x2; x1++)
                 {
                     if (cells[x1, y].name == "Empty(Clone)" || thiscell.name != cells[x1, y].name) break;
                     matchCount++;
                 }
                 if (matchCount >= 2)
                 {
                     x1 = Mathf.Min(cells.GetUpperBound(0), x1 - 1);
                     for (var x3 = x; x3 <= x1; x3++)
                     {
                         if (!stack.Contains(cells[x3, y]))
                         {
                             stack.Add(cells[x3, y]);
                          }
                     }
                 }
             }
         }
         return stack;
     }
 
     // Swap Motion Animation, to animate the switching arrays
     void DoSwapMotion(Transform a, Transform b)
     {
         Vector3 posA = a.localPosition;
         Vector3 posB = b.localPosition;
         TweenParms parms = new TweenParms().Prop("localPosition", posB).Ease(EaseType.EaseOutQuart);
         HOTween.To(a, 0.25f, parms).WaitForCompletion();
         parms = new TweenParms().Prop("localPosition", posA).Ease(EaseType.EaseOutQuart);
        HOTween.To(b, 0.25f, parms).WaitForCompletion();
     }
 
 
     // Swap Two Tile, it swaps the position of two objects in the grid array
     void DoSwapTile(GameObject a, GameObject b, ref GameObject[,] cells)
     {
         GameObject cell = cells[(int)a.transform.position.x, (int)a.transform.position.y];
         cells[(int)a.transform.position.x, (int)a.transform.position.y] = cells[(int)b.transform.position.x, (int)b.transform.position.y];
         cells[(int)b.transform.position.x, (int)b.transform.position.y] = cell;
     }
Comment
Add comment · Show 3 · 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 calebheale · Jul 25, 2014 at 05:15 AM 0
Share

I don't fully understand exactly what you are doing (honestly, I'm being a bit lazy because it is a lot of code). It does look like you are iterating the array to find matches though, which means my previous guess should be correct, in that you need to swap both the array positions and physical positions. I would also highly recommend that you leave out any animation logic until you get the basics working. It makes it much too difficult to debug.

I don't understand what the need is for _currentIndicator but since that is the only thing that I can see that you are destroying, I'm guessing that is where the other error is co$$anonymous$$g from.

Were you not able to append this to your original question? It is typically frowned upon to post something that isn't an answer as an answer and you could likely get downvotes from it.

avatar image RNVitter · Jul 25, 2014 at 11:38 PM 0
Share

found a different way to swap array and physical position now I just have to figure out why random tiles get deleted. Thanks for the help!

avatar image crunchyoverseas · Jul 25, 2014 at 11:58 PM 0
Share

Those nested If statements are pretty dicey...I feel like some of that should be unpacked into functions calls so it's easier to read, that is probably half the problem...as far as debugging the deleted object thing, use Debug.log to trace what is going on with those nested if's.

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

Problems with array "shuffle bag" 1 Answer

RandFuncs.Shuffle question 0 Answers

How to instantiate the first 8 gameobjects in an array (UnityScript)? 1 Answer

My loop keeps producing the same wrong result :,,( 2 Answers

Generate random no and active that GO using array 1 Answer


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