Slight Confusion between transform.Find and GameObject.Find

I’ve read in a couple of places that it’s better to use transform.Find eg -

child=transform.Find("left_arm");

because it will only look in through the hierarchy of that particular gameObject rather than the whole scene as would be the case with something like eg

child=GameObject.Find("left_arm");

However, what’s confusing for me is that I actually want to be able to treat the object on the end of the transform.Find as a game object and do things like destroy it or Itween it, neither of which are possible with transform.Find.

I definitely want to restrict the search to just the hierarchy of a particular game object, but also return an object that will be treated as a gameObject - what am I doing wrong here?

Thanks in advance :slight_smile:

Destroy(transform.Find("left_arm").gameObject);

–Eric

sigh I must have been about an hour and a half trying wrong variations of that simple line of code to get it to work, before you posted the correct syntax. I will not forget that in a hurry. Many thanks, Eric, I’ve learned something there :slight_smile:

Hmm,

After some days of messing around, I’m once again confused about transform.find. I was under the impression that it would return children of the transform of ONLY the object that had the script attached.

So I declare an object variable:

coinEmit=transform.Find("slot_coinemitter").gameObject;

which should target a child gameObject of a slot machine that instantiates a load of coins that drop out. This works absolutely brilliantly until I duplicate the slotmachine itself, so in the scene we now have two slot machines and two slot_coinemitters. If I activate the function on slotmachine2 that makes coins spit out, the coins don’t spit out of slotmachine2, they spit out of slotmachine1!

Trying to research the problem, I found a post by someone that seemed to have the same issue. The reply went:

Does it really have to be that complicated, targeting a child object, or have I made a massive gaff somewhere along the line? :face_with_spiral_eyes:

No it is not that complicated. I am not sure what the context of the quoted statement is ( “transform.Find(”“) is correlating to transform.gameObject.Find(”“),”, but without reference to some other code that someone might be doing, I don’t think the statement is true, at least not what it is suggesting.

transform.Find() - will find a child of the current transform by name - and that’s it. You would only do something recursive if you wanted to find a child of a child, but if the name is known then use just use “transform.Find( child/child )”

for your example:
coinEmit=transform.Find(“slot_coinemitter”).gameObject;

you do not really need to add .gameObject to the end of that. The reason it was added in the earlier example by Eric is because it is need to Destroy an full object and not a component of it (and you cannot destroy the transform only).

It is hard to determine form the one line and your scenario, and there may be an issue somewhere else in your code, but try removing the .gameObject reference in this case, because it can work just as well like this:

coinEmit=transform.Find("slot_coinemitter");
Instantiate( goldcoinprefab, coinEmit.position, coinEmit.rotation);

Thank you Priceap, you’re absolutely right, it was me writing wrong code. I need to have the coins popping out randomly along the x axis, so my code for this was

coinEmit=transform.Find("slot_coinemitter");
		coinPos=coinEmit.transform.position;		
		for (i=0;i<coinNum;i++){
			yield WaitForSeconds (0.05);		
			var randomPosition = Vector3(Random.Range(-0.2, 0.27), coinPos.y, coinPos.z);
			var randomRotation = Quaternion.Euler(Random.Range(0, 360) , Random.Range(0, 0)  , Random.Range(0, 90));
			slotPayout-=payVar;
			textpaid.text=slotPayout.ToString();
			var coin = Instantiate(coinPrefab, randomPosition, randomRotation);		
			etc

The bad line was

var randomPosition = Vector3(Random.Range(-0.2, 0.27), coinPos.y, coinPos.z);

because that means that the coins would always fall out at the position of the original slot machine’s coin emitter, I’m guessing.

It should have been

var randomPosition = Vector3(Random.Range(coinPos.x-0.2, coinPos.x+0.27), coinPos.y, coinPos.z);

I realise that I have another problem, namely when I press the ‘Cash In’ button EVERY coin emitter spits out coins and this was componunding the first problem. To check when the user presses a button on the slot machine, I use a raycast from the main camera

function Update(){	
		
	var hit : RaycastHit;

	if(Input.GetButtonDown("Fire1")) {
	    var ray : Ray = Camera.main.ScreenPointToRay(Input.mousePosition);		
        if(Physics.Raycast(ray, hit)){            
			var hitCollide = hit.collider.gameObject.name;			
				switch(hitCollide){
					case ("slot_button01"):
						buttonDown(hitCollide);
						cashIn();
					break;
					case ("slot_button02"):
						buttonDown(hitCollide);
						placeBet(1);
					break;
					case ("slot_button03"):
						buttonDown(hitCollide);
						placeBet(3);
					break;
					case ("slot_button04"):
						spinReels();
						buttonDown(hitCollide);
					break;
					case ("slot_coin_insert"):						
						insertCoin(hitCollide);					
					break;
					case ("slot_arm"):
						moveArmDown();
					
					break;
				}
		}
	}  
}

No matter which slot machine I’m using, pressing the ‘Cash In’ button calls the cashIn() function on every slot machine in the scene. I’m thinking the problem lies with

var hitCollide = hit.collider.gameObject.name;

Gah, I’m just being stupid! I needed to check that the player is in range of a slotmachine before they’re allowed to do the raycast. Because it’s in the onUpdate function, every time I press the left mouse button, each slotmachine is going to respond no matter where I am in the scene. Added an if (inRange) conditional and it now works as it should :slight_smile:

Thanks again priceap for putting me straight on the transform.Find :slight_smile: