How to Activate Random GameObjects from a list without affecting position
Hi there, I am trying to activate a random GameObject from a list, but anything I try also activates the GameObject at a random position for a random amount of time before it is deactivated.
Is there any way to activate a random GameObject from a list without affecting the position?
This is what my original code looks like before trying to randomize activation.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class poollist : MonoBehaviour {
public float fireTime = 2f;
public GameObject Log1;
public GameObject Log2;
public GameObject Log3;
public GameObject Log4;
public int pooledAmount = 10;
List<GameObject> Logs= new List<GameObject> ();
// Use this for initialization
void Start () {
for (int i = 0; i < pooledAmount; i++) {
GameObject obj1 = (GameObject)Instantiate (Log1);
GameObject obj2 = (GameObject)Instantiate (Log2);
GameObject obj3 = (GameObject)Instantiate (Log3);
GameObject obj4 = (GameObject)Instantiate (Log4);
obj1.SetActive (false);
obj2.SetActive (false);
obj3.SetActive (false);
obj4.SetActive (false);
Logs.Add (obj1);
Logs.Add (obj2);
Logs.Add (obj3);
Logs.Add (obj4);
}
InvokeRepeating ("Fire", fireTime,fireTime);
}
void Fire ()
{
for (int i = 0; i < Logs.Count; i++) {
if (!Logs [i].activeInHierarchy) {
Logs [i].transform.position = transform.position;
Logs [i].transform.rotation = transform.rotation;
Logs [i].SetActive (true);
break;
}
}
}
}
I've tried changing Logs [i].SetActive (true);
to Logs [Random.Range(0, Logs.Count)].SetActive (true);
, but it also activates the GameObject at a random position.
Yes I am new to coding, still finding my way around, and I've been sitting on this for too long. Any help will be greatly appreciated, if my question or code is too vague I'd be happy to clear it up. Thanks.
Answer by ToothPaste17 · Sep 01, 2016 at 08:58 AM
I think the problem is that you're setting the position and rotation of one gameobject, but activating a different one. Try changing your Fire method to this:
void Fire(){
int randomIndex = Random.Range(0, Logs.Count);
Logs[randomIndex].transform.position = transform.position;
Logs[randomIndex].transform.rotation = transform.rotation;
Logs[randomIndex].SetActive(true);
Logs.RemoveAt(randomIndex);
}
Hi there ToothPaste17, thanks for your reply. It does work, thank you so much. I am though having a different issue now. depending how big I make the pool, after a few seconds it gives me an "Argument out of range" error.
The method removes one item from the list each time it is called, until the list is empty eventually. But the method keeps trying to pull items from the pool even though it is empty, which causes the error. The solution is to check if the list is empty, and if so, either refill it or cancel the invoke. For example:
void Fire()
{
if(Logs.Count == 0)
{
CancelInvoke();
return;
}
int randomIndex = Random.Range(0, Logs.Count);
Logs[randomIndex].transform.position = transform.position;
Logs[randomIndex].transform.rotation = transform.rotation;
Logs[randomIndex].SetActive(true);
Logs.RemoveAt(randomIndex);
}
Thanks, I would have liked to mark your answer as accepted since its exactly what I've been looking for, but it's a comment. One last thing though, I've tried finding out for myself how and where to refill the list after it's emptied out, but I just can't come up with anything, I think I might be trying to over analyze it. For it's intended purpose the code, as it is, would work fine, I don't need to refill the list, but would you $$anonymous$$d helping me explaining how to go about refilling it so I could use it in future as well please?
Thanks again!