Realm Rush Editor - null ref exception

Hi,

I’ve been having some problems now that we are trying to de-couple the editor from the waypoints (or in my case tiles) for pathfinding. whenever I try to call the tile(waypoint) script class from the CubeEditor script its giving me a null reference exception that the instance of the script does not exist.

(for reference I’m in unity 2018.3.5f1)

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//[ExecuteAlways]
[ExecuteInEditMode]
[SelectionBase]
[RequireComponent(typeof(Tile))]
public class CubeEditor : MonoBehaviour
{

    //[SerializeField] Tile tile;
    Tile tile;

    private void Awake()
    {

        tile = GetComponent<Tile>();

    }

    // Update is called once per frame
    void Update()
    {
        SnaptoPlace();
        UpdateLabel();

    }



    private void SnaptoPlace()
    {
   
        int tileSize = tile.GetTileScale();
        transform.position = new Vector3(
            tile.GetTilePos().x * tileSize,
            0f,
            tile.GetTilePos().y * tileSize
            );

    }

    private void UpdateLabel()
    {
    
        int tileSize = tile.GetTileScale();
        string coordinates = 
            tile.GetTilePos().x / tileSize +
            "," +
            tile.GetTilePos().y / tileSize;

       TextMesh textMesh = GetComponentInChildren<TextMesh>();
        textMesh.text = coordinates;

        gameObject.name = "Tile (" + coordinates + ")";
    }
}

Anyways the crude way I’ve gotten around this for now is to set up the variable as a serializedfield so I can add it from inspector. Errors completely disappear then, but I wouldn’t exactly call it a solution.

Hi,

You’ve not mentioned the full error details, this would include the line number. Can you post a corresponding error with details which map to your code above?

Sorry I am having trouble generating the error message again, though it still doesn’t work unless I drag the actual script into the serialized field from the same object.

To the best of my memory the error was:

NullReferenceException: Object reference not set to an instance of an object

and it activated every time I went to use the tile I was trying to draw from GetComponent; (first time at line 34 (int tileSize = tile.GetTileScale();).

Basically the error was just that the GetComponent(); was not retrieving anything – I had to specifically drag in the actual script with the same class name from the same object as a serial of the editor script attached).

I’m going with this for now and hoping it does not cause problems in the future.

Do you actually have the Tile.cs script component attached to this GameObject? If you are getting a NullReferenceException error when using the GetComponent method I would suggest not.

You could either check by looking in the Inspector, or, after the GetComponent statement, use a Debug.Log to output to the console, for example;

private void Awake()
{
	tile = GetComponent<Tile>();
	
	if(tile)
	{
	    Debug.Log("Tile component retrieved");
	}
	else
	{
	    Debug.Log("No tile component found");
	}
}

If you test this, remove the [SerializeField] attribute for the tile member variable so that the Inspector doesn’t for the reference you are creating.

That’s what I had thought too, and now that we’ve gone through this I am hoping to understand where the mistake was since I’m having trouble breaking it now even without the [Serializefield] (though if I set the [Serializefield] to none now before removing it stops snapping until I press play again).

Does awake only get called once you press play in the editor even with [ExecuteInEditMode]? (I had the misconception it was otherwise. Now that I have played with it seems that commenting out the getcomponent and pressing play removes the reference and snapping no longer occurs until I undo the commenting and press play again).

You mentioned that removing the [Serializefield] attribute removes the previous inspector referencing as well, correct?

Awake will only be called once, per script, and with the [ExecuteInEditMode] attribute will not require you to click Play.

Unlike when you play the game, the Update method is also only called once, well, once per change that you make in the scene, it doesn’t run constantly like it would during the game running.

When you add the [SerializeField] attribute you are exposing an otherwise private member variable to the Inspector. If you have a default value that you assign in the script itself, when you declare the variable, any value within the Inspector will override it.

If you remove the [SerializeField] attribute the field will no longer be exposed within the Inspector, as such you are unable to set a value, Unity may cache what you had previously set, so if you added the attribute back again you may see what you had previously entered via the Inspector, but without the attribute the values will be based upon what is set in your code.


See also;

Thanks. Just one last thing to confirm since this seems to be the case when I test it anyways:

The editor awake is only called once, when the editor/project is originally opened, and never again no matter what changes you make.

(Note: that I screwed up the gitignore on my source control on this one and forgot to add it early on so I still have the library files this time)

1 Like

It will be called if the game is run, as it would be normally, if the scene changes, it would be called again (assuming the same script is in that scene also), so not once ever, depends on the circumstances.

If you need to get back to a specific point in time you could always use the Project Changes link from the Resources on Udemy, you will be taken to GitHub where you can then download a copy of the project as it was at that point in the course. You may want to consider having that as a separate project and just copy the scripts out from it and put into your own project etc to not wipe over your project entirely.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms