- Home /
GetComponent for siblings and parents
I'm trying to put together a battle system, and I've run into a few problems. I'm setting the enemies up to have nearly identical scripts and hierarchy so that they will be easy to reference later on for attacks and whatnot. The hierarchy looks like this (so far)
Enemy (GameObject) - is the main holder for all the enemy info, everything else is put into here.
Info (empty GameObject) with a two main scripts attached. The stats script, which has name, max and cur HP, max and cur MP and all that stuff. It has no real functions in it, just info and it will be the script that is accessed by all the other scripts. The second script is the character sheet scripts which has all the info for each new enemy. This script has functions that push the info into the stats script.
GUIStats (a guitext game object) that pulls from Info to display all the info within the Info game object from the stats script.
The character model that has the meshes and whatnot
and a targetter mesh ( a flat ring under the character model) that that I want to enable the renderer for when the enemy is targeted (a boolean variable in the stats script attached to the Info game object.
I had all of those scripts placed on a single guitext before and had everything working perfectly with GetComponent, (even using scripts from outside game objects to take away and add hp from the stats script) but when I tried to add the targetter mesh I ran into problems when getting components from other gameobjects within the Enemy game object (the parent to them all).
My question is, what is the best way to access components for siblings. For example, I need the script in GUIStats to pull from the Stats component in Info, and I need the script in targetter to access that Stats script as well to turn its renderer on and off.
The components I need to access have to call the instances of the scripts within the parent they are all under. I have tried looking online and haven't found a clear solid answer, just a lot of examples of referencing components on the same game object and from entirely separate game objects.
What I have now is a bunch of links to scripts on the same GameObject that look like this:
var HP : int;
var stats : Stats;
function Update () {
var stats = GetComponent(Stats);
HP = 20
stats.maxHP = HP;
which works when the two scripts are attached to the same place, but Im getting a lot NullReferenceException: Object reference is not set to an instance of an object errors when I try to mess around with getting the components that are attached to different GameObjects in the same parent.
Any help would be appreciated, thanks.
EDIT: Im probably doing things completely wrong, I'm new to scripting in the larger sense (I've written some code that did stuff attached to an object, but this is my first attempt and putting all the pieces together). My thinking was that I would have a main object with children attached that perform all the uniform functions that an enemy would do. Again Im just starting out with it, but the two things that need to be separate (so far) from the main object so far is the mesh for the circle that indicates its the target (which each enemy would have, it is just disabled when they aren't targeted) and the GuiText that floats above their heads (which needs a code I found on the internet that changes the location of everything its attached to in a weird way).
I've reread my post and Ill try to clarify a little better. I have the main object, which Ill refer to as the body, and other objects with scripts attached that do different that need to interact with each other, which Ill call the arms. I want an arm to say, this code that is attached to another arm on the same body Im on will do this to me. Its easy enough to call the script with:
GameObject.Find("body/arm").GetComponent(Wave)
from another body, but Im looking for how to say:
GameObject.Find("THISbody/anotherArm").GetComponent(Wave)
and if the answer is to call all the arm components from the body, how do I say:
GameObject.Find("Me/myArm").GetComponent(Wave)
I hope that makes any more sense. Thanks for bearing with me.
Answer by jogo13 · Jan 10, 2013 at 05:27 AM
It would be a be of a rewrite/reshuffled but i suggest a 'ai_core' class that handles all the other classes.
In it's startup it would go through any necessary attached gameobjects and grab components as necessary ONCE. (using getcomponent() per frame is a not recommended for performance reasons.)
The ai_core would then be able to access the hitpoints,etc and assign them to the gui_text and perform other cross component sharing in it's main (update) function
Keep all the cross gameobject/component access in this one 'manager' class to avoid 'spaghetti'd' code. --edit example mini class
class ai_core
{
GUIText guiText;
Stats stats
Start(){
guiText = GetComponent(GUIText);
stats = GetComponent(Stats);
}
Update(){
//update display
guiText.text = stats.hitpoints.ToString();
}
}
Is there a way to GetComponent in the Start function and then use those components in the update function? Ive had had trouble getting them to return when I put them in different places. Also is there no way to access the instances of the gameobjects and their components inside a parent? I had other ideas for doing that with other things.
Yes, i added a $$anonymous$$i (untested) sample class to the answer above.
Answer by robertbu · Jan 10, 2013 at 06:31 AM
I don't understand how you've structured your code, but I thought I might mention a couple of items:
You can get the parent GameObject like this:
GameObject goParent = transform.parent.gameObject;
Now with the parent, you can get an array of all components of a particular type attached to the parent and any of the parent's children (your siblings) with GetComponentsInChildren(). For example, say you are looking for all Rigidbodies:
Rigidbody[] arrb = goParent.GetComponentsInChildren<Rigidbodies>();
http://docs.unity3d.com/Documentation/ScriptReference/Component.GetComponentsInChildren.html