- Home /
Find a specific child of a GameObject with the collision data from OnControllerColliderHit
I've been able to find child objects in the past using for (var child : Transform in transform)
and I know that transform.Find
allows you to find the immediate children of the gameObject the script is attached to. However, I haven't had much success with either approach in this particular case.
I have a script on my First Person Controller to detect collisions with various objects and perform some kind of interaction. In this case i'm using OnControllerColliderHit to detect the collision with a bathroom sink model. When that happens, I want to activate one of the sink's children, a mesh called tap_water, to give the impression the water is running (i'll animate the texture later).
While I already know the name of both objects, I want to use the collision data stored in the 'hit' variable to interact with the specific object I have collided with (there will be a row of sinks, which i'll make into prefabs once I get it working). I want to be specific since I have another child ('bowl_water') which I want to activate and move separately too.
I'm going round in circles at the moment so would appreciate any help that can be given.
Thank you.
EDIT - Okay, I have another question now. I'll stick it here so I get the nice formatting. As per the previous script, when I collide with the sink object, I successfully find the child named "tap_water" and activate it. I've also now added another IF statement to play an animation on the sink which moves the "bowl_water" object up to give the impression that the bowl is filling with water. All well and good.
I have a final child object called "overflow" which is supposed to appear to suggest the water is overflowing the bowl. With another IF statement I can get it to show, but it appears before the bowl filling animation has finished. I need to check if this animation has finished and then show it. I've been trying to use the IsPlaying function but it never seems to happen, it's like the animation never finishes, even though it's set to 'once' and I'm also setting a boolean at the end of the first collision to make sure subsequent collisions don't trigger it. At the moment I have this:
for(var child : Transform in thisSink){
if(child.gameObject.name == "bowl_water"){ thisSink.animation.Play("fillUp"); }
if(child.gameObject.name == "overflow"){
Debug.Log("IT GETS THIS FAR BUT THE NEXT LINE HAS NO EFFECT");
if(!thisSink.animation.IsPlaying("fillUp")){
child.gameObject.active = true;
}
}
// the player has to be carrying the towel when they // first approach the sink. // Disabling it here so that animation won't play on subsequent approaches.
towelCollected = false;
}
Thanks again.
Answer by straydogstrut · Mar 30, 2010 at 04:51 PM
They do say that your brain keeps working on a problem while you're doing other things. I realised the reason the final part of my IF statement wasn't working is because I was only checking it once, when I collided with the object, rather than continuously from the Update function.
Reordering my code to accommodate this took a bit of work, but the end result is more compact and i've added the functionality for the player to flood a series of sinks before a timer starts which calls an NPC to investigate when it runs out, giving the player time to escape.
My code now is:
function OnControllerColliderHit (hit : ControllerColliderHit){
if(hit.gameObject.tag == "sink"){
// store a reference to the transform of the object we hit (the sink)
var thisSink = hit.transform;
// turn on the tap
thisSink.Find("tap_water").gameObject.renderer.enabled = true;
TextHints.message = "Too bad they took the plugs away...";
TextHints.textOn = true;
// if we have the towel
if(towelCollected == true){
// store a reference to the script on this particular sink
otherscript = thisSink.gameObject.GetComponent("sinkSetup");
if(!otherscript.hasFlooded){
// play the filling with water animation
thisSink.animation.Play("fillUp");
// set the local hasFlooded variable of this script to true
otherscript.hasFlooded = true;
// increment the number of sinks that have been flooded
sinksFlooded++;
}
}
}
}
Thank you to everyone who took the time to read my questions.
Answer by straydogstrut · Mar 30, 2010 at 01:43 AM
[This was my earlier response to my original question]
Oh I am silly! This seems to be working:
var thisSink = hit.transform;
for(var child : Transform in thisSink){ if(child.gameObject.name == "tap_water"){ child.gameObject.active = true; } }
If anyone has any other suggestions, please feel free to share. Otherwise i'll complete this Question in the morning. Thank you for your time.
Answer by hallamasch · Mar 02, 2011 at 11:27 AM
Any reason why you don't have your Code on the Bathroom Sink instead of on the Player. Generally I would think that would make more sense.