- Home /
C# issue, health, and destroying affect other objects.
I have a script i obtained in a tutorial, it works, but it didnt destroy the enemy after death. I'm trying to destroy a box on my test scene, i used another script to access this one and lower its health just fine. once it becomes 0 it dies and thats what i want. my other box doesnt use its health though, after the first box dissapears, and it was telling me in the error message that im trying to access this script, yet this script was destroyed, i tried other methods and i looked on google and websites for unity and c#, ive been searching for at least 3 days. can somebody help me find out why my script is becoming destroyed on all objects its attached to, and what i need to do to fight and kill each box seperately?
public void Die () {
Destroy(gameObject);
}
is what i believe is the problem, i think i need to find another method of righting this part.. if i remove this section, all else works as coded.. if i wrote it certain ways, it told me i couldnt change from bolean to int or vice versa?
Any help greatly appreciated im brand new to this site, been working on this game for months and very slow at learning if im picking things apart on my own, i learn much better with coaching/teaching aid.
using UnityEngine; using System.Collections;
public class EnemyHealth : MonoBehaviour {
public int maxHealth = 100;
public int curHealth = 100;
// Update is called once per frame
void Update () {
AddjustCurrentHealth(0);
}
public void AddjustCurrentHealth(int adj) { curHealth += adj;
if(curHealth <= 0)
Die();
if(curHealth > maxHealth)
curHealth = maxHealth;
}
public void Die () { Destroy(gameObject); } }
In this script, the function Die() would never be called. Because, curHealth will never be less than/equal to zero. Since, you have initialized the value of curHealth to 100, previously.
And you are passing "0" as the argument when you are calling the AddJustCurrentHealth() function. I am afraid, you have to change your logic.
What has to happen? If you let me know, I can help you.
I want to press "J" to subtract 10 Health, (Works) once i hit "J" 10 times, the 100 Heatlth becomes none and the boxes should vanish. however the script shows its on both boxes yet only one gets destroyed, after the first box "Dies" i attack the second box, and when i have reduced its Health to 0 it sends an error message and the box continues to attack no matter how many times i hit it, i know for a fact its health isnt set higher than i thought, and the script remains in the inspector attached to the box
error message says "$$anonymous$$issingReferenceException: The object of type 'GameObject' has been destroyed but you are trying to access it."
That is the same thing I am telling, the method Die() would not be called. That is where you are destroying the gameObject. Check again.
i did change it right after your post.
if(curHealth <= 0) changed to if(currentHealth < 1) Die(); Die();
i dont see a difference, and i have no idea what to set the addjustcurrentHealth(0); to under the update, you mentioned that before also.
Answer by Seth-Bergman · Apr 30, 2012 at 08:25 AM
I think maybe the other script you're using, to turn the health to 0, is still looking for the object once it's destroyed. Use a check, like:
if(otherScript) //reduce health
I suspect the other objects are remaining intact, try hitting pause and selecting one to see if it still has the script on it..
Answer by Punkjim420 · Apr 30, 2012 at 08:42 AM
I checked, and yes its still showing "EnemyHealth.cs" as being attached to my other box, thats the script above, the script below is "PlayerAttack.cs" which removes the health. but even with both scripts active, EnemyHealth.cs is not destroying the second box.
and thank you for your reply.
using UnityEngine;
using System.Collections;
public class PlayerAttack : MonoBehaviour { public GameObject target; public float attackTimer; public float coolDown;
// Use this for initialization
void Start () {
attackTimer = 0;
coolDown = 0.5f;
}
// Update is called once per frame
void Update () {
if(attackTimer > 0)
attackTimer -= Time.deltaTime;
if(attackTimer < 0)
attackTimer = 0;
if(Input.GetKeyUp(KeyCode.J)) {
if(attackTimer == 0) {
Attack();
attackTimer = coolDown;
}
}
}
private void Attack() {
float distance = Vector3.Distance(target.transform.position, transform.position);
Vector3 dir = (target.transform.position - transform.position).normalized;
float direction = Vector3.Dot(dir, transform.forward);
if(distance < 20.5f) {
if(direction > -0.7) {
EnemyHealth eh = (EnemyHealth)target.GetComponent("EnemyHealth");
eh.AddjustCurrentHealth(-10);
}
}
}
}
Answer by Seth-Bergman · Apr 30, 2012 at 09:13 AM
The next question, I guess, is: how are you setting the target? I assume you have the player script attached to the player, with the enemy script attached to each box. There needs to be something to set the variable "target" of the player to the next box. Anyway, you need to choose your target somehow, maybe a raycast since it looks like you want to be facing it to destroy it?
RaycastHit hit;
if (Physics.Raycast(transform.position, Vector3.forward, out hit))
{
if(hit.gameObject.tag == "enemy")
target = hit.gameObject;
}
you would need to tag all your boxes as "enemy". Something like this should set the current target to whichever you've most recently faced.
yeah, i have tagged all enemies as "Enemy" and i just doubled checked.
that was just an example.. say, for example, you could add:
if(!target)
target = GameObject.FindWithTag("enemy");
(in the player's Update function)
this should reload the target variable with the next box. (if your tag is "enemy", not "Enemy", it needs to be exact.) Of course, this would just pick the next box in line, if there were more than one. If you wanted more control over which box got picked next, you'd need to add more logic as to how to choose, but for now it sounds like you want small steps.. so try that to start
im not sure if i have something written to decide what my target is, i have tagged the enemies as "Enemy" for sure, and i checked my script, but i think its not checking the tags, only position.
ok, thank you i think i understand now, since i did in fact not have a target check yet. thanks for your help!
no prob. Also remember that you can still interact with the inspector while the play button is down. So, even while play is on, if you select your player object (from the hierarchy panel), the script(s) attached to it will become visible in the inspector panel. there you should see the variable "target", and whether it's set to anything (and even drag and drop an enemy to the slot to set it, if you like);
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
If health = 0, show a GUI.button C# 2 Answers
Distribute terrain in zones 3 Answers