So I’m trying to do something like: [if all objects with tag “ball” are all kinematic, do such and such].
I would be using GameObject.FindGameObjectsWithTag for it, but I don’t know how to evaluate a component across all instantiated instances of them.
Any help would be greatly appreciated!
EDIT: I could use an array to store all the objects returned with FindGameObjectsWithTag, but as there can be any number of objects in the array, it’s not really practical to reference the Rigidbody2D from each object since I can have 100+.
That’s pretty much what you’ll have to do. Create the array and loop through it. Unless you can tag stuff differently. FindGameObjectsWithTag will return an array, so you’ll have to loop through it to perform other checks or manipulate it.
The only other way is to create a list as you go. If you are instantiating the ball object through the game, then you can add it to a list if it’s kinematic. for example. Basically you would need to handle the object as it is created, destroyed, etc. Or if using a pool, manipulate it as you access the pool.
Thank you! I am looking into foreach or for loops to see which one would work best. (I’m not good at loops). But I can’t add the ball to the array during gameplay because I’m writing in C#, so I can’t add things to arrays, unless there’s a way to do it in C#?
IEnumerator LevelLost ()
{
// Wait for 1 second...
yield return new WaitForSeconds (1);
// For each element in the array...
for (int i = 0; i < balls.length; i++)
{
// If all elements in array are kinematic...
if (balls[i].GetComponent <Rigidbody2D>().isKinematic)
{
// Debug
print ("IT WORKS!");
}
}
}
The problem there is that it happens for every object and it doesn’t check it across all objects. I basically want to know that all objects in the array are kinematic before I go any further.
Any tips on reworking my if statement to have it check for all objects at once instead of each individual object?
NOTE: I have this script on every instantiated object.
You can’t just do a mass check, which is why I suggested adding to a list (not an array) as stuff passed the test. The other way to do it is if an object isn’t kinematic, you set a bool to false and exit the loop, then an if check after to determine what to do.
bool allKinematic = true; //assume they are all kinematic
for(int x = 1;x < list.Count;x++)
{
if(notKinematic check)
{
allKinematic = false;
break;
}
}
if(allKinematic)
//All are kinematic, do what you need
else
//At least one isn't kinematic, do something else.
This isn’t exact code, just a brief type up of how it may work.
public GameObject[] balls;
void Awake ()
{
balls = ballParent.GetComponent <ballParentControl>().balls;
}
IEnumerator LevelLost ()
{
// Wait for 1 second...
yield return new WaitForSeconds (1);
// For each element in the array...
for (int i = 0; i < balls.Length; i++)
{
// Set variable to know which ball is last
int lastBall = balls.Length
// If last element in array is kinematic...
if (balls[lastBall].GetComponent <Rigidbody2D>().isKinematic)
{
// Do stuff here
}
}
}
Turns out I don’t have to do the mass check. I only need to test the last object in the array (if the last object in array is kinematic, all the others are kinematic as well).
Thank you all for the help!
EDIT: Still tweaking it a bit to get it to work better. Will post finished script when done.
So no need for a loop of any kind. Just need to make sure you’re testing the last element in the array (the problem with the previous “solution” was that I was not updating the last element like I should have because it was in child script (which gets instantiated), so each ball instance would change the last element. By updating last element in parent script, it doesn’t fluctuate.
And another issue with the previous “solution” was that I didn’t subtract 1 from last element value. That is important because I have a ball present from Awake, so right off the bat I have one element in array, but it’s at index 0 by default. So that means index 0 means I have 1 ball, not 0, which messes up math when you have more balls. So -1 just makes it easier.
Confusing. If you need only check 1 item… why not just check the one? And if, again, just one item… there’s no need to create a new array of objects in Update (with FindGameObjectsWithTag).
Maybe if you explained a little about your situation you could get some feedback on improvements. =)
So I needed to use the array and FindGameObjectsWithTag because I needed all of those objects so I could find which one was last one (it is last one that I evaluate).
However, I have decided to not do what I was trying to do at the time since I realized that if the player had unlimited balls, they could spam them until game lags or crashes, and I can’t prevent that in a way that I would like, so it’s better to just have a max of 5 balls instead of unlimited balls, and no real need to have unlimited balls anyways.
I’m sure there is more practical way of doing what I was trying to do, but it worked for me
I guess what I’m getting at is that you could simply evaluate the last ball spawned or whatever (just on its own - no list/array required). Update it if one is newer*.