- Home /
How to deactivate an object in array which was chosen randomly before then activate randomly another one also in that array?
I don't even know if my question makes any sense or not but i will try to explain it well. The game is in 2D. I'm having a box which is basically an array containing objects (objects are being childs of player and also being deactivated). Those boxes are being instantiated randomly in the scene after a random amount of time.
When player collides with a box, it will make the player activate randomly an object which is a child of the player. What i want to achieve is: when the player collides again with another box and if the currently active object is still there, i want to make the player deactivate the currently active object and activate randomly another one. And so on.
Right now i have come with the solution in the script below, but it 's kinda buggy and i know this isn't the right way to do it. Sometimes it did the job, sometimes it activated 2 or more objects simultaneously. So if anyone has better solution, please help. Thank you for reading my question. Here is the script:
public GameObject[] Objects;
GameObject currentObject;
GameObject newObject;
int i;
int j;
private void Update()
{
i = Random.Range(0, Objects.Length);
currentObject = Objects[i];
j = Random.Range(0, Objects.Length);
newObject = Objects[j];
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "PickupAble")
{
if(currentObject.activeInHierarchy==false)
{
currentObject.SetActive(true);
Destroy(collision.gameObject);
}
}
if(collision.gameObject.tag=="PickupAble")
{
if(currentObject.activeInHierarchy==true)
{
currentObject.SetActive(false);
newObject.SetActive(true);
Destroy(collision.gameObject);
}
}
}
Answer by toddisarockstar · Sep 02, 2018 at 12:51 AM
there is no reason to put things in update unless they have to repeat every frame!!! this should be all you need
public GameObject[] Objects;
public int c = -1;
private void OnCollisionEnter2D(Collision2D collision)
{if (collision.gameObject.tag == "PickupAble")
{ if(Objects.Length>1){
int n = Random.Range(0, Objects.Length);
//this line ensures you dont pick the same one from before
while(c==n){n = Random.Range(0, Objects.Length); }
Objects[n].SetActive(true);
if(c>-1){Objects[c].SetActive(false);}
Destroy(collision.gameObject);
c=n;
}else{print ("oops there is only one item"); }}}
It worked like a charm. However since i don't have a strong background in program$$anonymous$$g, i'm trying to wrap my head around your code. Could you please explain it more detaily?
everything in the OnCollistionEnter brackets only happen once each time you have a collition. everything in void Update brackets repeats everyframe. in other words, code in update generally repeats around 40 to 80 times a second depending on FPS.
in program$$anonymous$$g proficiency is just as important as seeing things work. your previos code had your random assignments hapenning in update. but really the random selection and everything we are accomplishing only need to happen once when we have the collition so i got rid of the update function for this script.
i took out the part where you check if activeInHiearchy. if you know all the objects are set to not active when you start, and this is the only code changing this factor, then we are keeping track of the current active in the code and dont need to ask.
between collitions we are storing which object is active in the Integer variable c!
notice i store the index number for the array ins$$anonymous$$d of using a Gameobject variable to represent the acvive object. if we used a GameObject variable we wouldn't know where it was in the array!!!!!
this is good habit in program$$anonymous$$g as you learn more and get into more advanced checking with loops and arrays.
anyways look at line number 7. we choose a random index number.
remembering that "c" is holding the number or the current active Index number, look at line 9. if you are not familiar with the "while" loop.. the code in the {} brackets repeat untill the condition in the () brackets is true. on line 9 if the cpu has choose the same number as the active Index, it will keep randomly picking till it is different. now we are magically guaranteed we have a different number than our current number. horray! (this is our temorary "n" variable).
looking at line 10,11....... "n" now represents our soon to be current active. so can safely disable the "c". and enable the "n".
Line 13...... now we store "c" to equal our temporary "n" for next time around!!!!
as far as the other lines. line 6 is just a safe guard. I love while loops but they are dangerous because if you enter a while loop and the condition is not meet it can create an Infinate loop which freezes the code and can freeze the game and the unity editor. im not sure exactly what your doing over there but if your array size ever got down to one i wouldnt want to crash you!!! Haha. you could take out line 6 if your sure your array will allways be bigger than 1.
on line 2 i set "c" to -1. this is just so that i know when you are having your first virgin collition!! on line 11 I can see that there is no active object yet so i wont bother to disable anything. the -1 also skips the while loop the first time so the random selection is not limited the first time around.