- Home /
How to make an array list set to false gradually instead of instantly?
Below is the code for setting all the array in my list to false instantly. So what I would like to achieve is to set the list of array to false gradually.
(example: example I have 10 box in the scene when I click on object 2 I would like to show object 1 and 2 then the rest of the object in the array will set to false gradually)
Anyone have any ideas how I could achieve the effect?
public GameObject[] test;
public void ArrayObj() {
for (int i = 0; i < test.Length; i++)
{
test[i].SetActive(false);
}
test[0].SetActive(true);
test[1].SetActive(true);
}
Answer by Casiell · Oct 19, 2018 at 06:45 AM
You should use coroutines for that. When you have a coroutine you just put yield return inside the for loop and specify how long you want to wait.
Below is an example of what you want with 1 second intervals:
public IEnumerator SetInactiveGradually()
{
for (int i = 0; i < test.Length; i++)
{
test[i].SetActive(false);
yield return new WaitForSeconds(1);
}
}
Just remember, t ostart a coroutine you have to use:
StartCoroutine(SetInactiveGradually());
Hi Casiell.. but is it possible to make it start from the last array as in 10 9 8 7 ? cause currently its disappearing from 1 2 3 4 5 6
With the function I gave, you can give the indices you want and loop through the array in reverse order:
for ( int i = endIndex - 1 ; i >= startIndex ; i--)
Yes, just change the for loop to:
for (int i = test.Length - 1; i >=0; i--)
Answer by Hellium · Oct 19, 2018 at 06:47 AM
public void ArrayObj()
{
StartCoroutine( TurnOffGameObjects( test, new WaitForSeconds( 0.1f ), 2 ) ;
test[0].SetActive(true);
test[1].SetActive(true);
}
private IEnumerator TurnOffGameObjects( GameObject[] gameObjects, YieldInstruction wait = null, int startIndex = 0, int endIndex = -1 )
{
// Clamp the indices to have valid values regarding the array length
startIndex = Mathf.Clamp( startIndex, 0, gameObjects.Length ) ;
if( endIndex < 0 ) endIndex = gameObjects.Length ;
else endIndex = Mathf.Clamp( endIndex, startIndex, gameObjects.Length ) ;
// Turn off the gameObjects and wait between two deactivations
for ( int i = startIndex ; i < endIndex ; i++)
{
gameObjects[i].SetActive(false);
yield return wait ;
}
}
HI Hellium thanks for the answer its works as well !! but i went with casiell answer as he's code is shorter and easier to use
@Hellium omg thanks !! your code seems much better now because there's so much I could do with it .. but one last question is it possible to make it after 5-10 object then the WaitForSeconds to be faster? because currently if i change the (new WaitForSeconds( 0.1f )) to 0.001f it doesn't make any difference. you two really help me so much ! O$$anonymous$$G Cheers buddy
I see two possibilities, using a function to compute the delay between two spawns according to the index of the spawned object
private IEnumerator TurnOffGameObjects( GameObject[] gameObjects, System.Func<int, float> delayFunction, int startIndex = 0, int endIndex = -1 )
{
// Clamp the indices to have valid values regarding the array length
startIndex = $$anonymous$$athf.Clamp( startIndex, 0, gameObjects.Length ) ;
if( endIndex < 0 ) endIndex = gameObjects.Length ;
else endIndex = $$anonymous$$athf.Clamp( endIndex, startIndex, gameObjects.Length ) ;
// Turn off the gameObjects and wait between two deactivations
for ( int i = startIndex ; i < endIndex ; i++)
{
gameObjects[i].SetActive(false);
yield return new WaitForSeconds( delayFunction( i ) ) ;
}
}
public void ArrayObj()
{
// Will wait 10 seconds between object 0 and 1
// then, 5 seconds between 1 and 2
// then 3.33 seconds between 2 and 3, etc....
// You can use the function you want to compute the delay
StartCoroutine( TurnOffGameObjects( test, index => 10f / index, 2 ) ;
}
Or using an AnimationCurve, which is more "visual"
private IEnumerator TurnOffGameObjects( GameObject[] gameObjects, AnimationCurve delayCurve, int startIndex = 0, int endIndex = -1 )
{
// Clamp the indices to have valid values regarding the array length
startIndex = $$anonymous$$athf.Clamp( startIndex, 0, gameObjects.Length ) ;
if( endIndex < 0 ) endIndex = gameObjects.Length ;
else endIndex = $$anonymous$$athf.Clamp( endIndex, startIndex, gameObjects.Length ) ;
// Turn off the gameObjects and wait between two deactivations
for ( int i = startIndex ; i < endIndex ; i++)
{
gameObjects[i].SetActive(false);
yield return new WaitForSeconds( delayCurve.Evaluate( i ) ) ;
}
}
// Edit the curve in the inspector
// The horizontal axis represent the index of the object
// The vertical axis represents the delay between two deactivations
// The point (x,y) of the curve will represent the delay (y) between the spawn of object x and x+1
public AnimationCurve delayCurve ;
public void ArrayObj()
{
// Will wait 10 seconds between object 0 and 1
// then, 5 seconds between 1 and 2
// then 3.33 seconds between 2 and 3, etc....
// You can use the function you want to compute the delay
StartCoroutine( TurnOffGameObjects( test, delayCurve, 2 ) ;
test[0].SetActive(true);
test[1].SetActive(true);
}
@Hellium Thanks man.. the image below is the curve that I made I set it to a value of 0.02/0.02 but I cant seems to make the object hide faster it's hiding the object the same rate as a coroutine 0.1f. Cant seems to make it go below that value or making the hiding faster.
Because what's I'm trying to achieve is I have 100 object in scene when I click on object 40 I would like to hide every object above that value. As what you did with the code it works perfectly "StartCoroutine( TurnOffGameObjects( test, new WaitForSeconds( 0.1f ), 40 ) ;" but i would like to make the hiding of the object faster currently it's to slow.