When you destroy the game object, it destroys all child components, including the script.
Well I feel your pain, been stuck on critical problems that prevented me from moving forward and learning, so I’ll try to help you out. A GameObject in Unity at its core is just a hierarchical Point. An empty game object, for instance, simply represents a 3D point in space. You can then add child game objects to that one to form child-parent relationships so that if you move the parent, the child follows, and if you rotate the parent, the child rotates around the origin of the parent (quite useful really).
You can add scripts in much the same way. Although you don’t see the script outlined as a separate child game object in the Scene Hierarchy editor, it is attached closely to the game object such that if you delete it, it will be destroyed as well.
Don’t think of the term “Destroy” as meaning “I killed an enemy”. Destroy means removing the point and all children/scripts on it and below it from the game.
Now assume you are still trying to call a script on this game object that you have destroyed, which I believe is the case here. Then you are trying to ask a dead person to talk back to you. It just ain’t gonna happen (well let’s not get into that debate). In fact, the game crashes, because it doesn’t know what to do. It just assumes you made a mistake. Imagine if it just went on its merry way and ignored your commands, how hard it would be to find those bugs. The crash is really a way to tell you to fix your logic. Your code is fine, but the logic is not. When you compile your game, the code syntax and form is being verified, but when you run it, things like this happen to prevent logic flaws (well also because the engine doesn’t know what to do when you tell it to go run code that doesn’t exist anymore).
So what is the solution? I kind of offered one in an earlier comment, but I’ll clarify. You really shouldn’t have the GUI code in a script attached to the enemy if you want to continue rendering the score GUI after the enemy dies. Create a new script that just renders the score, and attach it to an empty game object in your scene. Then add some static methods to update the score, like this:
public class ScoreRenderer : MonoBehaviour
{
public float HealthBarLength;
static public float score = 0;
void Start()
{
HealthBarLength = Screen.width / 3;
}
static public SetScore(float value)
{
score = value;
}
void OnGUI()
{
GUI.Box(new Rect(900, 10, HealthBarLength ,20), score.toString());
}
}
I simplified what you had to just displaying a single float value, but I want to make this as simple as possible, then you can get it working and complicate it from there. Now you have a nice simple score rendering class that you can attach to an empty game object, and from your EnemyScript, you would just call it like this:
ScoreRenderer.SetScore((float)curHealth / maxHealth);
The next thing you need to fix is stop calling AdjustCurrentHealth() externally. I assume you are calling it by reference? I mean, you have another script on a different game object (let’s call it ScriptA), and you have dragged the Enemy game object onto that script over a public GameObject in the property inspector so that script can call this AdjustCurrentHealth method? If so, you need to fix that. Make it so that the script knows when the enemy is dead.
Again, for simplicity, just use a static variable, so in ScriptA:
public static bool enemyDead = false;
public GameObject enemyReference; // This is the public variable you drug the enemy game object onto in the editor (if you did)
void Update()
{
if (!enemyDead && SomeWeaponHitEnemyJustNow)
{
enemyReference.AdjustCurrentHealth();
}
}
Then in your EnemyScript, right after you check for health <= 0:
ScriptA.enemyDead = true;
Hopefully this will get you on your way.