- Home /
More efficient Scripting.
Hello, I'm still learning C#, and I ran into whats not really a problem, but what I feel can be heavily improved upon.
The objectClock clock will not be counting in 5s, that's just for a test as the, but I still feel it could be improved. I will be adding more objects to the objectClock and change the clock variable to call the NewRandomObject function at different times.
I don't like the fact that the NewRandomObject function has to call itself over and over to find a new object if its already active. I was wondering if there's a way to check the objects array and grab only inactive objects?
It works for what I need it to do and was just wondering if y'all had any ideas that could make it cleaner and more efficient.
using UnityEngine;
using System.Collections;
public class ObjectTimer : MonoBehaviour {
private GameObject[] objects;
private GameObject randomObjects;
private int clock = 0;
private void Start()
{
objects = new GameObject[transform.childCount];
for (int i = 0; i < transform.childCount; i++)
{
objects[i] = transform.GetChild(i).gameObject;
}
StartCoroutine("objectClock");
}
private IEnumerator objectClock()
{
while (true)
{
yield return new WaitForSeconds(1);
clock ++;
Debug.Log (clock);
if(clock == 1)
{
NewRandomObject();
}
if(clock == 5)
{
NewRandomObject();
}
if(clock == 10)
{
NewRandomObject();
}
if(clock == 15)
{
NewRandomObject();
}
if(clock == 20)
{
NewRandomObject();
}
if(clock == 25)
{
NewRandomObject();
}
if(clock == 30)
{
NewRandomObject();
}
if(clock == 35)
{
NewRandomObject();
}
}
}
private void NewRandomObject()
{
randomObject = objects[Random.Range(0, objects.Length)];
if(randomObject.activeInHierarchy == true)
{
Debug.Log("Object already active; finding new object");
NewRandomObject();
}
else
{
randomObject.SetActive(true);
}
}
}
Answer by Hellium · Jul 14, 2015 at 12:39 PM
This is what I would have done :
using UnityEngine;
using System.Collections;
public class ObjectTimer : MonoBehaviour {
private GameObject[] objects;
private GameObject randomObjects;
private int clock = 0;
private void Start()
{
objects = new GameObject[transform.childCount];
for (int i = 0; i < transform.childCount; i++)
{
objects[i] = transform.GetChild(i).gameObject;
}
StartCoroutine("objectClock");
}
private IEnumerator objectClock()
{
for( int clock = 0 ; clock < 36 ; ++ clock )
{
yield return new WaitForSeconds(1);
if( ( clock % 5 ) == 0)
{
NewRandomObject();
}
}
}
private void NewRandomObject()
{
int startIndex = Random.Range( 0, objects.Length );
int index = 0;
// Look for the first active object starting at a random index
for ( index = startIndex ; !objects[Random.Range(0, objects.Length)].activeInHierarchy ; ++index )
{
// Prevent infinite loop
if ( index - startIndex > objects.Length )
return ;
}
randomObject = objects[index] ;
}
}
Where would you activate the randomly selected object, and what if you wanted to customize the clock to activate one random object at, say, 3 seconds and another at 8 seconds?
Oops, I missed the first point. Didn't see it. I changed the condition inside the for loop then.
private void NewRandomObject()
{
int startIndex = Random.Range( 0, objects.Length );
int index = 0;
// Look for the first inactive object starting at a random index
for ( index = startIndex ; objects[Random.Range(0, objects.Length)].activeInHierarchy ; ++index )
{
// Prevent infinite loop
if ( index - startIndex > objects.Length )
return ;
}
objects[index].SetActive(true) ;
}
About the clock, if you don't want it to be regular, define a public array of int / floats called spawnTimes, and modify the coroutine as follow :
private IEnumerator objectClock()
{
for( int clockIndex = 0 ; clockIndex <= spawnTimes.Length ; ++clockIndex )
{
yield return new WaitForSeconds(spawnTimes[clockIndex ]);
NewRandomObject();
}
}
Then, in your inspector, you can specify the different times you want the NewRandomObject() to be called.
I made a mistake in the for loop of the coroutine, make sure you have corrected it.
(I edited my last comment)
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Unsuccessfully trying to clamp my player object 0 Answers
Weird functioning lists 0 Answers
C# Creating a More Efficient Script 4 Answers