- Home /
Check if there is a child with a tag? (multiple children but each diff tag)
Ok, after a few days I finally give up, so I come to you wise Unity community.
I have a player with weapons. When the player collides with a weapon on the ground it activates this process that I cant figure out how to do. Might need to read the next part a bit slower... sorry I'm confused too.
Upon collision the weapon on the ground checks if there is already a weapon with its tag in the transform that holds all of the weapons, holstered(inactive) and not(do not question my methods! hehe joking) and then if one of the children in that transform has its tag, it will give that child ammo and destroy it self, and if there isn't a child with that tag, it will add it self to the transform with the rest of the weapons.
Now here's where the problem starts. If we have an if statement with "if a tag with my tag is there, add ammo to it and destroy it self" and an else if with "if a tag with my tag isn't there, add self there" the second will always be true, because there will always be a child with a different tag in the transform. So that's what I don't know how to get around.
Here's the basic layout of the code, to spare you the unnecessary details. Thanks for reading this far. xD
function OnTriggerEnter (other : Collider)
{
var triggered = true; //just a bool to make sure only one of the happens cause of said problem
if(other.gameObject.tag == "Player" && isPickup) //if collided with player and im a pickup
{
for (var child : Transform in playerCamera.transform)
{
if(child.gameObject.tag==myTag && triggered) //if weapon in players inventory is same tag as mine
{
//Add ammo code (leaving it out to keep it short)
}
else if(child.gameObject.tag!=myTag && triggered)
{
//Adds self to the inventory
}
}
}
}
Note: I tried DOZENS of variations with the if statements there combining some like if tag isnt my tag and if tag is my tag, and other combinations, but none worked out. I don't know, instinct tells me I'm not using the "for" part right, but I don't know how else to write it.
Thank you!
Are your weapons supposed to be children of playerCamera?
Yes they are. They're also using the same script as pickups and weapons, just different parts are activated/deactivated if they're serving one purpose or another, not that that is important in this case.
In this case the code seems ok. To start troubleshooting, I suggest debugging or simply printing the tags using Debug.Log(child.gameObject.tag)
as a first line inside for statement.
I did everything I could think of, including debugging, I'm at this for about 2-3 days now. xD
The problem is both if and else if happen in this case. "if(child.gameObject.tag==myTag)" happens when there is that tag among children, but the "else if(child.gameObject.tag!=myTag)" also happens too cause even tho there is that tag like in the "if" part, there's also differently tagged children so they trigger the "else if" too.
EDIT: If I remove the bool part, if I don't only the else if happens.
Answer by ArkaneX · Nov 06, 2013 at 03:28 PM
Ok - after exchanging comments I got the problem :)
To do what you want, you have to first gather all children tags and then check against these tags, to find out if any of them matches your tag. An example below (requires importing System.Collections.Generic and System.Linq namespaces).
var childrenTags : List.<String> = new List.<String>();
for (var child : Transform in playerCamera.transform)
{
childrenTags.Add(child.tag);
}
//if(triggered)
//{
if(childrenTags.Any(function(x) x == myTag))
{
print("child with the same tag found");
}
else
{
print("child with the same tag not found");
}
//}
EDIT: commented out bool part after seeing your edit :)
EDIT2: to get a component, use a slightly different approach:
var children : List.<Transform> = new List.<Transform>();
for (var child : Transform in playerCamera.transform)
{
children.Add(child);
}
var childWithSameTag = children.SingleOrDefault(function(x) x.tag == myTag);
if(childWithSameTag != null)
{
print("child with the same tag found: " + childWithSameTag.name);
// here you can easily get a component, because you have actual transform
}
else
{
print("child with the same tag not found");
}
Of course you can change this code to not use list/extensions/lambdas too:
var childWithSameTag : Transform = null;
for (var child : Transform in playerCamera.transform)
{
if(child.tag == myTag)
{
childWithSameTag = child;
break;
}
}
if(childWithSameTag != null)
...
But I like LINQ approach more :)
Aaaah thank you it works! Finaly. x'D
Can you please explain it to me how exactly does what you did work, I never used lists before(if those are lists), or imported anything, and have no clue whats going on. I don't like using someone else's script without knowing how it works and how to do it my self. So if you have some extra time would you kindly explain each line? xD
$$anonymous$$ost importantly how do I get a component of the child with the same tag found?
No problem :)
Generic list is an object allowing you to store a number of elements of specified type. In contrary to arrays, lists allow manipulating element, i.e. inserting, removing. I suggest reading more in $$anonymous$$SDN page and in Unity Wiki. The generic list I used is defined in System.Collections.Generic namespace, and that's why import is required.
Now to the next thing - Any
method. This method is not defined in a List class, but ins$$anonymous$$d is defined in a separate class as so called extension method. I won't go into details here, but I suggest reading more in $$anonymous$$SDN page and watching short video in Unity docs.
$$anonymous$$any useful extension methods are defined in Enumerable class, belonging to System.Linq namespace. Numer of these methods accept a parameter which is so called lambda expression. Originally these expressions were feature of C#, but were implemented into UnityScript by Unity $$anonymous$$m (with a bit different syntax). I won't go into details related to lambda expressions as well, because you can find many related resources in the net. I suggest starting from $$anonymous$$SDN page and from Unity official docs.
A lot to read I assume, but believe me - it's worth it :)
Yes - break causes exit from loop. As to the LINQ - I prefer it, because in many cases it makes code look much cleaner. It's not good to use it everywhere though, because its performance might be worse than non-LINQ solutions in some cases.