Search Unity

Problem trying to add point when killing enemy

Discussion in 'Scripting' started by Marianomiguel, Sep 11, 2019.

  1. Marianomiguel

    Marianomiguel

    Joined:
    May 8, 2016
    Posts:
    3
    Hello dear forum people
    I am trying to make a simple system to score points by killing an enemy.
    I have two scripts

    I have a Game Controller script:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.UI;
    4.  
    5. public class GameController : MonoBehaviour
    6. {
    7.     public Text scoreText;
    8.     private int score;
    9.  
    10.     void Start()
    11.     {
    12.         score = 0;
    13.         UpdateScore();      
    14.     }  
    15.  
    16.     public void AddScore(int newScoreValue)
    17.     {
    18.         score += newScoreValue;
    19.         UpdateScore();
    20.     }
    21.  
    22.     void UpdateScore()
    23.     {
    24.         scoreText.text = "Score: " + score;
    25.     }
    26. }
    27.  
    And the script that is put on the enemy:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class DestroyAndScore : MonoBehaviour
    5. {  
    6.     public int score;
    7.     private GameController GameController;
    8.  
    9.     void Start()
    10.     {      
    11.        
    12.     }
    13.  
    14.     void OnTriggerEnter(Collider other)
    15.     {      
    16.        
    17.         if (other.tag == "bullet")
    18.         {          
    19.             GameController.AddScore(score);
    20.         }              
    21.        
    22.     }
    23. }
    The problem is that it does not add the points when executed. I get an error on the last line:

    GameController.AddScore(score);

    Best regards and thanks
     
  2. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    633
    Neither the GameController class or AddScore method are static so you require a reference to the GameController class instance.
     
  3. Marianomiguel

    Marianomiguel

    Joined:
    May 8, 2016
    Posts:
    3
    My problem is that I don't know how to solve that. Any suggestions?
    Regards!
     
  4. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    6,511
    You could make the GameController on line 7 public instead of private, and assign it in the inspector. That would solve the immediate problem. On the other hand, you'll have to do that for every object that needs to affect the score, and that gets cumbersome.

    Game managers are good candidates to be singletons - objects for which there is one and only one copy in the scene, which can be referenced easily from anywhere, using a static reference. A word of caution: You do have to be cautious about using singletons because they're so ridiculously easy to use that rookies will end up using them too much, in situations where it's not appropriate to and will cause issues down the line. For example, while it may be true now that you only have one Player object, that's probably not actually a good use for singletons because you may decide later to add multiplayer or AI enemies or teammates later on, and having singleton-based code will make that transition harder. They can also make your script files more heavily intertwined with each other, which makes it harder to reuse code between projects. Generally speaking, good places to use singletons are game managers, game UIs, and level information containers (where there will be one per scene, so only one exists at any given time).

    So with that out of the way, here's the most basic possible singleton:
    Code (csharp):
    1. public class GameController : MonoBehaviour {
    2. public static GameController instance;
    3.  
    4. void Awake() {
    5. instance = this;
    6. }
    7.     public void AddScore(int newScoreValue) {
    8. //... and all your other existing code....
    9. }
    10. }
    Now, anywhere else in your code, you can do this:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class DestroyAndScore : MonoBehaviour
    6. {
    7.     public int score;
    8.  
    9.     void OnTriggerEnter(Collider other)
    10.     {  
    11.      
    12.         if (other.tag == "bullet")
    13.         {      
    14.             GameController.instance.AddScore(score);
    15.         }          
    16.      
    17.     }
    18. }
    You don't need to declare anything or do any preparation; GameController.instance is always there, accessible, from anywhere in your code, as long as there's a GameController object in your scene. (It's possible to write a singleton in such a way that it will create one if one doesn't exist, too, but let's start simple) For game manager classes this is great. Just be careful about overusing this concept, as mentioned above.
     
    Marianomiguel likes this.
  5. Marianomiguel

    Marianomiguel

    Joined:
    May 8, 2016
    Posts:
    3
    Thank you very much for the reply. The truth helped me a lot since they are new to csharp.
    Greetings and thanks again!!!