Best way to destroy an enemy in 2D enviroment and add score

Hi, currently i’m trying to make a simple game in which the player (a plane) has to shoot at enemies and goals. i don’t know if it’s good scripting at all, but i’ve done so that if the enemy is destroyed, another object (let’s call it Detector) adds 5 to the score (i’m not taking the score from the player’s script (i wouldn’t know how to do it), so i’ve created the value in this Detector’s script) that is displayed by the game manager (that also displays just fine the health and the lives of the player). i’ve done this because if i do the same thing from the enemy, whenever it’s destroyed the score stops counting and i get the error of the NullReference. but now my problem is that the enemy destroyed is always null of course, so the object just keeps adding and adding.
this is the code in my game manager and the game object called “DetectCollision” is the object i previously called Detector.

void Update () {
        GameObject player = GameObject.FindGameObjectWithTag("Player");
        if(player == null)
        {
           
            if(Input.anyKey)
                Application.LoadLevel(Application.loadedLevel);
        }
        GameObject charcater = GameObject.FindGameObjectWithTag("Player");
        if(charcater != null)
        {
        GameObject livesHealth = GameObject.Find ("Player");
        livesHealth.GetComponent<Player>().Display();
        }else{
            Debug.LogError("Couldn't find the Player");
        }
        GameObject score = GameObject.Find("DetectCollsion");
        score.GetComponent<DetectEnemyCollision>().DisplayScore();

    }
   
}

i think that there is a way to take an int (or a float or anything and not a function) from a script and change its value from another one, but i just can’t get my head around it:hushed: (i’m pretty much a mess with the whole GetComponent thing)
so could you tell what is the best way to destroy something and count the score without having the problem of a null reference? how would you handle this? thank you for your time:)

It probably isn’t the best practice but if you make it a public static int you can then call it from other scripts by ScriptName.intName

1 Like

hi, first of all, thank you for your quick respond. i’ve tried what you suggested but i get this error: Assets/Scripts/GameController.cs(35,32): error CS0117: Player' does not contain a definition for score’

the code looks like this:

void Update () {
        GameObject player = GameObject.FindGameObjectWithTag("Player");
        if(player == null)
        {
            //Instantiate(particles, transform.position, Quaternion.identity);
            if(Input.anyKey)
                Application.LoadLevel(Application.loadedLevel);
        }
        GameObject charcater = GameObject.FindGameObjectWithTag("Player");
        if(charcater != null)
        {
        GameObject livesHealth = GameObject.Find ("Player");
        livesHealth.GetComponent<Player>().Display();
        }else{
            Debug.LogError("Couldn't find the Player");
        }
        //GameObject score = GameObject.Find("DetectCollsion");
        //score.GetComponent<DetectEnemyCollision>().DisplayScore();
        if(Input.GetKeyDown(KeyCode.G))
        {
            Player.score +=7;
        }
    }

i’ve marked as comment the previous part that took the score from the enemy, and just to test it i wrote that the g key is pressed the score value (that now is in the player’s script) is incremented by 7. could you explain the error? thank you once again!

Is Player the name of the script that has the score stored on it? & it might be static public int, I don’t have a PC handy so I can check what it is.

yes it is: in the player script i had the score int. any suggestions?
anyway for the last 30 minutes (sorry if im driving you nuts! it’s just that i dont have a great understanding of c# or unity) i’ve tried this different method:
i stopped trying to display the score from the game controller and i’ve started displaying it directly from the DetectCollision object, and its script looks something like this:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class DetectEnemyCollision : MonoBehaviour {
    public int score;
    public Text scoreText;

    public GameObject enemy;
    public bool enemyDead;
    // Use this for initialization
    void Start () {
        score = 0;

    }
   
    // Update is called once per frame
    void Update () {
        if(enemy == null)
        {
            enemyDead = true;
        }
        if(enemyDead == true)
        {
            score += 5;

        }
        DisplayScore();
   
    }
    public void DisplayScore()
    {
        scoreText.text = "Score: " + score;
    }

}

and as of now i don’t get any errors (which is always nice ;)) and in the game it says “score: 0” which is the initial value of the score, but if i kill the enemy it doesn’t increment at all. i was wondering if this happens because i used the enmy prefab as the reference in the DetectCollision object. any thoughts?:smile:

is this script on the player or the enemy? Do you kill the enemy by hitting them with the player or a bullet or something?
Depending on what I’m doing with the player I either store the score on the player script or on a manager script attached to an empty game object. Then whenever the enemy is killed, before I destroy it, I pass the score change across to the script managing the total score e.g if my score is on a manager script called Manager I make it static public int score then
Manager.score += (whatever the points are for destroying that enemy);

this script is on the DetectCollision object which is invisible while you’re playing and has only this script attached to it. the enemy is killed by a bullet that the player shoots. so in my case the score in calculated and displayed by a script (the one i posted in my last comment) in an empty game object (as i was saying, the DetectCollision, which doesn’t detect collisions at all now that i think about it, so the name doesn’t reflect it’s job).

so while you manage the score between the player and the empty game object, i did mostly the same thing but between the enemy (which in regarding this topic, the score, just becomes null when destroyed instead of your case in which the player has the score stored in it) and the empty game object (which should set to true a bool when the enemy is null and add 5 to the score)

So, you don’t need a bool to adjust the score. When the enemy collides with the bullet, or when it’s health reaches 0 (depending whether it has one shot kills or not), you want to just add to the score on your detect collision script. If all that script is doing is storing score then setting a bool to true & adding to the score if the bool is true then you have to many steps, just update the score directly when the enemy dies.

The next problem I see is that you have linked it to the enemy prefab & only changing the bool if enemy is null but I don’t think this ever happens. You also never reset your bool back to false (but as above, I don’t believe you actually need this bool).

What I’d do is:
Make the score int static public.
Remove the bool & score adjustment from this script & just keep the bit that displays the score.
On the bullet or enemy script (wherever you are doing the collision & enemy destroy stuff) add:
DetectEnemyCollision.score +=5;
In the line before you destroy the enemy. If your enemies aren’t a 1 shot kill make sure you check the enemy health before you increment the score & destroy them.

1 Like

okay, you cannot even imagine how grateful i am! thank you so much, you solved the problem! it works perfectly
thank you, thank you, thank you:):slight_smile: