- Home /
Is there any way to edit variables inside other scripts without declaring them as static?
I am aware that questions similar to this may have been asked many times already but I believe my situation may be unique.
In my current game I have some basic enemies, their health is displayed via the use of a plane that is floating above their heads, facing the camera. I have different textures which I change around at different health levels to indicate how much health the enemy has left.
The player can press tab to target different enemies, and left click to attack the current target, which accesses the enemies health variable and subtracts 1 from its value.
The problem I am having, is that when I attack one enemy, health is removed from every enemy in the scene, no matter how far away they are.
I already made a post on the unity3d subreddit and they told me that the problem was that I have the variable set as static.
However, if I try setting this to any other type (I have tried all that I know of, static, public, normal) I receive a NullReferenceException error when the player try's to attack an enemy.
Following is the code for the script which controls the players targeting and attacking.
private var target : GameObject;
private var attackDistance = 3;
var targetIndicator : GameObject;
var targetInfo : GameObject;
function Update()
{
if (Input.GetKeyDown ("tab") && (FindClosestEnemy() != null))
{
target = FindClosestEnemy();
var oldIndicator = GameObject.FindWithTag ("targetIndicator");
Destroy (oldIndicator);
var targetHealth = target.GetComponent(EnemyHealth);
Instantiate (targetIndicator, target.transform.position, target.transform.rotation);
}
if (target != null)
{
if (Input.GetButtonDown ("Fire1") && (Vector3.Distance(target.transform.position, transform.position) < attackDistance))
{
targetHealth.health -= 1;
}
}
}
function FindClosestEnemy () : GameObject
{
// Find all game objects with tag Enemy
var gos : GameObject[];
gos = GameObject.FindGameObjectsWithTag("Enemy");
var closest : GameObject;
var distance = Mathf.Infinity;
var position = transform.position;
// Iterate through them and find the closest one
for (var go : GameObject in gos) {
var diff = (go.transform.position - position);
var curDistance = diff.sqrMagnitude;
if (curDistance < distance) {
closest = go;
distance = curDistance;
}
}
return closest;
}
function clearTarget ()
{
target = null;
}
Following this, is the script which controls the enemies health, and updates the health bar accordingly.
var healthBar : GameObject;
var healthFull : Texture;
var health5 : Texture;
var health4 : Texture;
var health3 : Texture;
var health2 : Texture;
var health1 : Texture;
static var health : int = 6;
function Update ()
{
if(health > 6)
{
health = 6;
}
switch(health) { case 6: healthBar.renderer.material.mainTexture = healthFull; break;
case 5: healthBar.renderer.material.mainTexture = health5; break;
case 4: healthBar.renderer.material.mainTexture = health4; break;
case 3: healthBar.renderer.material.mainTexture = health3; break;
case 2: healthBar.renderer.material.mainTexture = health2; break;
case 1: healthBar.renderer.material.mainTexture = health1; break;
case 0: var oldIndicator = GameObject.FindWithTag ("targetIndicator"); Destroy (oldIndicator); Destroy(gameObject); break; } }
Answer by Seth-Bergman · Jul 24, 2012 at 10:03 PM
the problem is this line :
var targetHealth = target.GetComponent(EnemyHealth);
you are declaring the var targetHealth INSIDE the if statement...
just move the declaration outside of the if statement:
function Update(){
var targetHealth : EnemyHealth;
if (Input.GetKeyDown ("tab") && (FindClosestEnemy() != null))
{
target = FindClosestEnemy();
var oldIndicator = GameObject.FindWithTag ("targetIndicator");
Destroy (oldIndicator);
targetHealth = target.GetComponent(EnemyHealth);
//...etc
}
because of the scope, if it is declared inside the if statement, it only exists inside the statement..