Can't figure out this error.

So it’s probably something stupid but I can’t seem to figure it out…

I’m making a system where when you touch the “coin”, it gives +1 to the score and goes away, but I’m running into some issues. Here’s the main code with the text on it. (I know, it’s a lot more than just player movement on that script, but I’m just now learning how to make scripts talk to eachother…)

Here’s what’s on the player:

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

public class PlayerMovement : MonoBehaviour
{

    public float speed = 5.0f;
    public float jumpHeight = 20.0f;
    public float minX;
    public float maxX;
    public Text scoreText;
    private int score;
    private bool colorSwitch = true;
    private bool isGrounded = false;
    private Rigidbody2D myRigid;


    void Start ()
    {
        myRigid = this.GetComponent<Rigidbody2D> ();
        score = 0;
        scoreText.text = "Coins: " + score.ToString();
    }
   
    void Update ()
    {
        if(Input.GetKeyDown (KeyCode.S))
        {
            colorSwitch = !colorSwitch;
        }

        if(colorSwitch)
        {
            this.GetComponent<SpriteRenderer> ().color = Color.black;
        }
        else
        {
            this.GetComponent<SpriteRenderer> ().color = Color.white;
        }

    }
    void FixedUpdate ()
    {


        if (Input.GetKeyDown (KeyCode.Space) || Input.GetKeyDown (KeyCode.W) || Input.GetKeyDown (KeyCode.UpArrow))
        {
            if (isGrounded)
            {
                myRigid.velocity = new Vector2 (myRigid.velocity.x, jumpHeight);
                Debug.Log (" I am jumping ");
            }
        }

        if (Input.GetKey (KeyCode.A) || Input.GetKey (KeyCode.LeftArrow))
            {
                   
                myRigid.velocity = new Vector2 (-speed, myRigid.velocity.y);
                Debug.Log (" Moving RIGHT ");

            }

        if (Input.GetKey (KeyCode.D) || Input.GetKey (KeyCode.RightArrow))
            {

                myRigid.velocity = new Vector2 (speed, myRigid.velocity.y);
                Debug.Log (" Moving LEFT ");

            }

        if (myRigid.position.x <= minX)
        {
            myRigid.position = new Vector2 (minX, myRigid.position.y);
        }
        else if (myRigid.position.x >= maxX)
        {
            myRigid.position = new Vector2 (maxX, myRigid.position.y);
        }
           
    }

    void OnTriggerEnter2D ()
    {
        isGrounded = true;
        Debug.Log (" Detecting ground ");
   
    }

    void OnTriggerExit2D ()
    {
        isGrounded = false;
        Debug.Log (" Not touching ground ");

    }

    void OnCollisionEnter2D ()
    {
        if (myRigid.CompareTag ("Coin"))
        {
            setScore ();
        }
    }

    void setScore ()
    {
        if (CoinDestroy.isCollected == false)
        {
            score = score + 1;
            scoreText.text = "Coins: " + score.ToString ();
        }
    }
}

Here’s what’s on the coins:

using UnityEngine;
using System.Collections;
public class CoinDestroy : MonoBehaviour
{
    static public bool isCollected = false;


    static void OnCollisionEnter2D(Collision2D col)
    {
        if (col.gameObject.tag == "Player")
        {
            col.gameObject.SetActive (false);
            isCollected = true;
        }
           
    }
}

Error message:

As you can see, the only way I’ve figured out how to do this is to set it invisible instead of destroying it.

Any tips? Is there an easier way to approach this? This seems like a lot for just a coin I can pick up. I’ve watched the tutorials and looked through their code and can’t figure out why mine isn’t working.
An explanation would be awesome as well… Thanks guys.

Well it seems since you’ve edited the code, that error message’s line number doesn’t match up. It says you have a null object in your Start() method in your PlayerMovement script.

It’s probably scoreText. Are you assigning that in the inspector properly?

Null reference means that you tried to access a variable that was holding nothing. So maybe “scoreText.text =” threw a null reference because “scoreText” didn’t have a reference, and you tried to access the “text” property of nothing.

When in doubt, null check:

if(scoreText != null){
    scoreText.text = "score";
}

Also just some tips, get all your components in Start() or Awake(). You almost never want to use GetComponent inside Update(). Unless things are gaining and losing components during gameplay, you only need to use “GetComponent” once to get it, then you can continue to use it throughout your class. So create variables to store your component references.

You don’t need to do “this.GetComponent”, without “this” will work just fine.

You definitely DO NOT want to make “isCollected” a static variable of CoinDestroy. That means that every single Coin will share that one variable. If one coin sets that, it will be set for all of them.

Try something like this:

using UnityEngine;
using System.Collections;
public class CoinDestroy : MonoBehaviour {
    public int value = 1;

    private void OnCollisionEnter2D(Collision2D col) {

        // try to get the PlayerMovement component of whatever the coin collided with
        PlayerMovement player = col.gameObject.GetComponent<PlayerMovement>();

        // if the 'player' variable isn't null, that means we hit something with a PlayerMovement component
        if(player != null) {

            // add this coin's value to the player's score
            player.addScore(value);

            // destroy this coin gameobject
            Destroy(gameObject);
        }
    }
}

Then in your PlayerMovement script, you should get rid of the collision code (generally collision should be handled just on one of the two colliding objects), and have a function called “addScore” like this:

public void addScore(int points) {
    score += points;
    updateScoreText();
}

private void updateScoreText(){
    scoreText.text = "Coins: " + score.ToString();
}

You can also have your existing “setScore” to set the value directly, but I think addScore will be useful to you. I also added a function to update your score string, which you can call any time you change the score.

I’m getting all types of errors when trying to change things up like you said.
Updated code:

PlayerMovement:

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

public class PlayerMovement : MonoBehaviour
{

    public float speed = 5.0f;
    public float jumpHeight = 20.0f;
    public float minX;
    public float maxX;
    public Text scoreText;
    public int addScore;
    private bool colorSwitch = true;
    private bool isGrounded = false;
    private Rigidbody2D myRigid;


    void Start ()
    {
       
    }
   
    void Update ()
    {
        if(Input.GetKeyDown (KeyCode.S))
        {
            colorSwitch = !colorSwitch;
        }

        if(colorSwitch)
        {
            this.GetComponent<SpriteRenderer> ().color = Color.black;
        }
        else
        {
            this.GetComponent<SpriteRenderer> ().color = Color.white;
        }

    }
    void FixedUpdate ()
    {


        if (Input.GetKeyDown (KeyCode.Space) || Input.GetKeyDown (KeyCode.W) || Input.GetKeyDown (KeyCode.UpArrow))
        {
            if (isGrounded)
            {
                myRigid.velocity = new Vector2 (myRigid.velocity.x, jumpHeight);
                Debug.Log (" I am jumping ");
            }
        }

        if (Input.GetKey (KeyCode.A) || Input.GetKey (KeyCode.LeftArrow))
            {
                   
                myRigid.velocity = new Vector2 (-speed, myRigid.velocity.y);
                Debug.Log (" Moving RIGHT ");

            }

        if (Input.GetKey (KeyCode.D) || Input.GetKey (KeyCode.RightArrow))
            {

                myRigid.velocity = new Vector2 (speed, myRigid.velocity.y);
                Debug.Log (" Moving LEFT ");

            }

        if (myRigid.position.x <= minX)
        {
            myRigid.position = new Vector2 (minX, myRigid.position.y);
        }
        else if (myRigid.position.x >= maxX)
        {
            myRigid.position = new Vector2 (maxX, myRigid.position.y);
        }
           
    }

    void OnTriggerEnter2D ()
    {
        isGrounded = true;
        Debug.Log (" Detecting ground ");
   
    }

    void OnTriggerExit2D ()
    {
        isGrounded = false;
        Debug.Log (" Not touching ground ");

    }

    void OnCollisionEnter2D ()
    {
        if (myRigid.CompareTag ("Coin"))
        {
            updateScoreText ();
        }
    }
       

    public void addScore(int points) {
        addScore += points;
        updateScoreText();
    }

    private void updateScoreText(){
        scoreText.text = "Coins: " + addScore.toString();
    }
}

Error:

You’ve got a variable name:
public int addScrore on line 13

and a Method/Function name
public void addScore(int points) on line 104

It’s best to rename your functions just like you did with the previous functions, with upper case letters. It’s let you know the difference between a function name and also a variable.

//Variable name to keep current score
public int addScore = 0;

//Function name to add points to addScore
public void AddScore(int points)
{
  //Add score code in here
}

Have a look through this video to better understand how things work in C#, it’s not that long either :smile:.
https://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/coding-for-the-absolute-beginner

1 Like

You never gave your variable “myRigid” a value. You need to put this in your start function:

myRigid = GetComponent<Rigidbody2D>();

Then anywhere you use “GetComponent()” you can replace with “myRigid”