- Home /
Accessing variables from GameObjects in an array
I have several enemys which are all tagged with "pivot". They each have a script on them called "enemyHUD". This script contains a variable called, "enemyName". I would like to be able to display this variable from every gameObject using OnGUI. So far I have been able to build an array of poition vectors from the gameObjects using FindGameObjectsWithTag. But my attempt to poulate the variable "enemyName" for display results in crashing unity.
var enemyscript : enemyHUD;
function Start() { // to get an array of references to all those objects: enemyName = enemyscript.GetComponent(enemyHUD).enemyName; }
function OnGUI() // This function handles all GUI and is run multiple times per frame {
// floating healthbar GUI above the Opponent from array
var locations : GameObject[] = GameObject.FindGameObjectsWithTag("pivot");
for (i = 0; i < locations.Length; i++) {
enemy = locations[i];
enemyVector = enemy.transform.position;
enemyName = enemy.GetComponent(enemyHUD).enemyName; //THIS LINE CAUSES CRASH
namePos = camera.WorldToScreenPoint (enemyVector); // uses WorldToScreenPoint to get screen cordinates of enemy target
GUI.Label(Rect(namePos.x,namePos.y, 100, 50), enemyName);
}
Answer by skovacs1 · Jul 13, 2010 at 03:55 PM
General problems that could be omissions
You never close your OnGUI.
You may have just omitted from your included code, but there are two immediate problems that I see with this script:
1 What are enemyName, enemy, enemyVector, and namePos within the code sample you've provided? They appear to be undeclared. consider adding the declarations like:
var enemy : GameObject;
var enemyvector : Vector3;
var enemyName : string;
var namePos : Vector2;
2 What is enemyscript within the code sample you've provided? It is never assigned. Your types are a bit confusing. In enemyscript.GetComponent(enemyHUD).enemyName;
, you have an uninitialized enemyHUD script (enemyscript) on which you are calling GetComponent to get an attached enemyHUD script? This will always return null even if enemyscript were initialized. Then you try to access its enemyName variable and what do you expect to get? Perhaps you meant:
//get some game object to get the enemyHUD script of.
enemyscript = someGameObject.GetComponent(enemyHUD);
enemyName = enemyscript.enemyName;
Coding practices
Consider naming your variables something clearer. locations is storing GameObjects, but the GameObject's transform.position would actually store the location, not the GameObject itself, especially if it also has a script storing the enemyName.
For simplicity, have you considered using a foreach equivalent?
for (var enemy : GameObject in locations){}
Potential problems
Is the enemyName of the script accessible within this scope?
As names are case sensitive, be sure that everything is spelled and cased correctly. Is enemyHUD the correct name of the script exactly?
Does the enemy in the locations array have an enemyHUD script attached? If not, then the GetComponent is returning a null object and when you try to access the enemyName of this null object, you are trying to access something that doesn't exist which could be problematic. Try checking for null:
var script = enemy.GetComponent(enemyHUD);
if (script == null)
{
Debug.Log("No enemyHUD script attached!", enemy);
continue;
}
enemyName = script.enemyName;
To find this kind of crash problem yourself, try breaking your function calls up to isolate the function causing your problem and comment out any unneeded code that you know to be working. Also, use debug and print statement to trace the values (like printing the size of the array and current index to check your array indexing if using an indexing for loop or printing the names or IDs or object of the GameObjects to find which one is in error).
Try something like:
var enemyName : string; var enemyscript : enemyHUD; var enemies : GameObject[];
function Start() //initialize enemy array { enemies = GameObject.FindGameObjectsWithTag("pivot"); }
function Update() //enemies won't likely change more than once per frame { enemies = GameObject.FindGameObjectsWithTag("pivot"); }
function OnGUI() // This is run multiple times per frame { for (var enemy : GameObject in enemies) { enemyscript = enemy.GetComponent(enemyHUD);
if (enemyscript == null)
{
Debug.LogWarning("No enemyHUD script attached!", enemy);
continue;
}
enemyName = enemyscript.enemyName;
}
}
This is a great explaination for my rather unclear question. As you found, there were several areas where I did not completely understand how the parts where working together. I was able to get the script working correctly using your example. I hope this will help many beginners understand these concepts better.
Answer by TMM · Jul 13, 2010 at 12:01 PM
enemyName is not a member of a component. Its just only name. So try:
enemyName = enemy.GetComponent(enemyHUD).name;
And for your game performance its better to use FindGameObjectsWithTag once in the start function.
This still results in a crash for me. I'm not sure if you mean to make this change on the first or second instance of this line. Also, "enemyName" is the variable that I'm trying to access in each gameObject in the array, so I don't think that is the problem.
Answer by Tetrad · Jul 13, 2010 at 03:49 PM
If Unity itself is crashing (i.e. not the game not working), make sure your property isn't causing an infinite loop.
This will cause unity to break:
string enemyName
{
get { return enemyName; } // infinite loop;
}
In general, properties and class names are upper case to prevent issues like this:
public class EnemyHUD : MonoBehaviour
{
string enemyName; // private member variable
public string EnemyName // public property
{
get { return enemyName; }
}
}
See also this question
You're right about a function that calls itself causing a crash, but the sampled code is unityscript, meaning that there may not in fact be any classes or functions defined to expose private member variables as public properties. It is unlikely that this is the problem.
Your answer
Follow this Question
Related Questions
Adding variables from all scripts 2 Answers
Finding the Sum of Values of Multiple GameObjects in an Array + Variable Sized arrays 0 Answers
View script variables within an array of scripts in Inspector 1 Answer
Accessing other gameobject's script variables : why doesn't this work? 2 Answers
Problem with variables and inspector 1 Answer