- Home /
Using Tag to find Child and execute Scripts
Hello, I am in University and I have learnt Java, but no C# as like a dolt I didnt take the module for it. However next semester I am going to do a module for Unity and maybe my project with Unity.
To come to the point, I am currently not interested in the efficient way to do something, but how to access items and the general flow of C# and Unity; so I set goals for myself and try to work out how to do it, this gains me understanding of the interaction.
The Hierarchy, of the setup is Player -> Weapon Root -> Weapon -> BulletSpawn.
![alt text][1] [1]: /storage/temp/12202-playerspreadimage.png
So what I am doing is I have made the program work so in the arangement depicted above, bullets appear and are provided a force to fly out from the camera.
if( Input.GetButtonDown("Fire1") ){
Camera cam = Camera.main;
GameObject thebullet = (GameObject)Instantiate(bullet_prefab, cam.transform.position, cam.transform.rotation);
thebullet.rigidbody.AddForce( cam.transform.forward * bulletImpulse, ForceMode.Impulse);
Nice and simple, now what I want to do is from a script on WeaponRoot, which will handle the current weapon in use; I need a way to say "find this child" ive been trying Tags so I will explain with that. I want the script in Weapon root to say "look for child with Tag Weapon" and then use the reference to the weapon to do the same to find it's child with the Tag 'BulletSpawn'.
What I want to do this for is that I can then move onto having an active weapon, automatically detect that, find its BulletSpawn and fire bullets from its unique barrel.
WeaponBarrel = transform.FindWithTag("Weapon/BulletSpawn");
GameObject thebullet = (GameObject)Instantiate(bullet_prefab, WeaponBarrel.transform.position, WeaponBarrel.transform.rotation);
thebullet.rigidbody.AddForce( WeaponBarrel.transform.forward * bulletImpulse, ForceMode.Impulse);
The above is my latest attempt, and provides a long error of: Assets/Scripts/Shoot.cs(35,50): error CS1061: Type UnityEngine.Transform' does not contain a definition for
FindWithTag' and no extension method FindWithTag' of type
UnityEngine.Transform' could be found (are you missing a using directive or an assembly reference?)
Last little bit, here is the top bit of my code:
using UnityEngine;
using System.Collections;
public class Shoot : MonoBehaviour {
public GameObject bullet_prefab;
float bulletImpulse = 10f;
private GameObject WeaponBarrel;
// Use this for initialization
void Start () {
Thanks for any help, if possible dont just fix the code if you can, but explain why mine doesnt work and why yours does.
Answer by Tarlius · Jun 20, 2013 at 01:06 PM
FindWithTag is a GameObject method, not a Transform method.
Swap the "transform" for "GameObject", as shown in the usage example in the documentation.
Edit: Depending on the type of WeaponBarrel, you may also need to do a GetComponent or add a .transform to the end.
Thanks, I think I may need to clear some things up. Weapon Barrel is an Empty at the front of the barrel, I recently saw this used on the Tutorials being used for what I am trying to do.
What I am trying to do is ins$$anonymous$$d of attaching the Empty to the script for the spawn, I want to TAG find the Empty and use its position and rotation for the spawning of the bullets.
Any clarity questions, please ask.
What is an "Empty"? An GameObject with no scripts on it?
In case it wasn't clear, by type I mean like "typeof(WeaponBarrel)". Ie: Transform/GameObject/ArbitraryGunBarrel$$anonymous$$onoBehavior. FindByTag() will return a GameObject, so if WeaponBarrel is not of type GameObject you'll get another compiler error if you don't add a GetComponent.
I feel it probably worth noting that using a tag to find the object would be rather slow, so be sure to cache the result
Either way, you will need to find the GameObject first, and then get whatever you need from it, or have the script register with the class via a singleton method or something.
Since it doesn't sound like you have anything special on the object, you probably are trying to get its transform, which would simply be GameObject.FindByTag("YourTag").transform;
, which would be shorthand for
GameObject weaponBarrelGameObject = GameObject.FindByTag("YourTag");
Transform weaponBarrel = weaponBarrelGameObject.transform;
Ok I get some of that, I am really new to this; by Empty I mean: "GameObject -> Create Empty (Ctrl+Shift+N) "
Just to make sure, I am using C# I forgot to mention that.
Is an Empty not a GameObject?
So what I have tried now is:
//Find the E$$anonymous$$PTY and assign it to an object reference GameObject ObjectTag = GameObject.FindWithTag("BulletSpawn"); //Get the transform component and put that into a Transform object Transform BulletPos = ObjectTag.GetComponent();
//Then use the transform information to fire the bullet. GameObject thebullet = (GameObject)Instantiate(bullet_prefab, BulletPos.transform.position, BulletPos.transform.rotation); thebullet.rigidbody.AddForce( BulletPos.transform.forward * bulletImpulse, Force$$anonymous$$ode.Impulse);
![alt text][1] [1]: /storage/temp/12214-emptyobject_hi.png
For all I know, its not possible, but feels like the kind of thing that should be.
Also, how are you doing the code blocks, the Ctrl+$$anonymous$$ feature on here isn't doing it for me.
Create Empty will create an empty GameObject, yeah. But there is no "Empty" object, if you know what I mean. Your capitalisation made me think perhaps it was a class is all.
The code looks good, is it not working as expected?
I think you may want to use rigidBody.constant force or perhaps velocity (since a bullet doesn't have a constant force on it), although it will depend what sort of effect you intend to achieve
Answer by OP_toss · Jun 20, 2013 at 05:44 PM
Like Tarlius said, FindWithTag is not a Transform method, it is for GameObjects.
BUT I'd also like to point out some bigger issues with your code:
Finding objects with tags can be slow. It's also a string-based lookup, requiring string comparisons, which is slow. I suggest looking at the children directly, through the parent's transform.
transform.GetChildAt(0).gameObject; //get the first child's gameobject
This avoids having wierd redundant hierarchical information in Tags. It's also much faster as a lookup. If there's multiple children you can loop through children, or use a GetComponentInChildren
if there's a specific type of child you're looking for.
Also, member variables in C# are never capitalized. Only Classes/Structs/Enums and the like are. So I'd change WeaponBarrel to weaponBarrel.
Hope this helps!
But caching the result would be faster still. I kinda assumed he was searching from outside the parent to be needing a tag (otherwise just linking would be easier, no?) but if this is not the case and there is a reason to not just link, then this is sound advice.
The coding guidelines is also sound advice (note I did this in my code snippet to be more subtle :p )