Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Randomizing Objects Positions When Scene is Loaded (memorygame)

Discussion in 'Scripting' started by SuloSounds, Mar 10, 2020.

  1. SuloSounds

    SuloSounds

    Joined:
    Feb 13, 2020
    Posts:
    9
    Hi!

    I'm really just couple of weeks into C# and Unity so don't laugh if I don't understand.
    I tried to go through all threads with similar questions but it didn't really work for me.

    So I'm making a 3D memory game where 3rd Person can walk on objects and the objects play a sound. The player is supposed to find 8 pairs of the same sound to win. The 16 objects are in 4 by 4 formation on the scene.

    The problem is that I would like the 16 object to be randomly placed in the same 4 by 4 formation when the scene is loaded.

    I've made a public Vector3[] ObjectPositions, of all the 16 possible positions
    I've also tried making public GameObject[] Plates of all the 16 objects but I really don't know how to proceed with this.

    Code (CSharp):
    1.  
    2. public class positions : MonoBehaviour
    3. {
    4.     public Vector3[] Objectpositions;
    5.     public GameObject[] Plates;
    6.     private void Start()
    7.     {
    8.        
    9.            
    10.        
    11.     }
    12. }
    13.     }
    MuistiPeli.png
     
  2. adi7b9

    adi7b9

    Joined:
    Feb 22, 2015
    Posts:
    181
    I think the easiest way to do this is by mix up the indexes:
    Code (CSharp):
    1.  
    2. int[] rndIdx { get; set; }
    3.  
    4. void Start()
    5. {
    6.     var size = Plates.Length;
    7.     rndIdx = new int[size];
    8.     for (int i = 0; i < size; i++)
    9.     {
    10.         rndIdx[i] = i;
    11.     }
    12.     RandomIndexes(size, 2);//here is mixing up indexes 2 times
    13. }
    14.  
    15.  
    16. void RandomIndexes(int size, int mixesUp)
    17. {
    18.     Random rnd = new Random();// this is from .NET
    19.     //var rnd = Random.Range(0,size); <- you can use this
    20.     for (int mix = 0; mix < mixesUp; mix++)
    21.     {
    22.         for (int i = 0; i < size; i++)
    23.         {
    24.             var x = rnd.Next(0, size);
    25.             var t = rndIdx[i];
    26.             rndIdx[i] = rndIdx[x];
    27.             rndIdx[x] = t;
    28.         }
    29.     }
    30. }
    31.  
    Later on you need to use
    Code (csharp):
    1.  
    2. Objectpositions[rndIdx[ yourIndex ]];
    3.  
    4. //like
    5. for (int i = 0; i < n; i++)
    6. {
    7.   Vector3 pos = Objectpositions[rndIdx[i]];
    8.   //pos is a random position from your Objectpositions
    9.   GameObject plate = Plates[i];//you took the plate
    10.   plate.tranform.position = pos;// and place it at your random position
    11. }
    12.  
     
  3. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    A similar idea to the above that might be a bit easier to understand, C# has built-in types that make some of this easier. In particular, List<T> is a collection that's similar to an array, but it has some nicer properties like being able to add elements to it whenever you want. So I would modify your code slightly to use those:
    Code (csharp):
    1. using System.Collections.Generic;
    2.  
    3. public class positions : MonoBehaviour
    4. {
    5.    public List<Vector3> objectPositions; // The <> brackets here specify what type of List this is, or what each element's type is. So, this is a list of vectors.
    6.    public List<GameObject> plates; // This is a list of GameObjects. I'm guessing these aren't prefabs, so they are objects that already exist in the scene. If you dragged them in from the Project panel, they are prefabs; if you dragged them from the scene view or hierarchy, they are scene objects.
    7.  
    8.    public void Start()
    9.    {
    10.       // First, we'll make a temporary list that holds all of the plates. This won't change the list that already exists.
    11.       List<GameObject> remainingObjects = new List<GameObject>(plates);
    12.  
    13.       // for loops are one of the most important control structures for programmers. If you haven't seen them before, check out the learn section. Loops are one of the main super-powers of a computer.
    14.       // Loop through each object position, pick a random object, and put that object in the given position
    15.       for(int i = 0; i < objectPositions.Count; i++)
    16.       {
    17.           // Pick a random remaining object
    18.           int index = Random.Range(0, remainingObjects.Count);
    19.           GameObject randomObject = remainingObjects[index];
    20.  
    21.           // Remove the object we chose from the pool of remaining objects
    22.           remainingObjects.RemoveAt(index);
    23.          
    24.           // Move the object to the position we are currently trying to fill
    25.           randomObject.transform.postion = objectPositions[i];
    26.       }
    27.    }
    28. }
     
    Last edited: Mar 10, 2020
  4. SuloSounds

    SuloSounds

    Joined:
    Feb 13, 2020
    Posts:
    9

    Hey!
    Thanks so much for the answers, you're amazing!

    I got it working even though to be honest I don't absolutely understand everything that's going on.
    But I'm now definitely inspired to go learn c# more so I will understand it in the future.