2

I'm making quick 2 player game in Unity and I came up with this:

using UnityEngine;
using System.Collections;

    public class PlayerClient : MonoBehaviour {

    public string username;
    public RaceType currentRace = RaceType.Human ;
    GameObject playerMob;
    Player currentPlayer;
    ClientController attachedController;
    // Use this for initialization
    void Start () {
        attachedController = gameObject.GetComponent (typeof(ClientController)) as ClientController;
        if(attachedController == null)
            Debug.LogError("Could not create attachedController!");
    }

    // Update is called once per frame
    void Update () {

    }

    public void MovementInput(float x, float y, float z){
        playerMob.transform.Translate (x, y, z);
    }

    public void FinishCharacterCreation(){
        switch (currentRace) {
        default:
            break;
        case RaceType.Human:
            playerMob = Instantiate (Resources.Load ("Human", typeof(GameObject))) as GameObject;
            currentPlayer = playerMob.AddComponent<Player> () as Player;
            attachedController.enabled = true;
            break;
        }
    }
}

In there are 3 classes; PlayerClient, Player and ClientController.

The one shown is PlayerClient (obviously). Player is a blank slate (at this point in time) and ClientController is just a basic thing used in conjunction with networking.

I get this error:

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

on lines 24 & 34, which as you'll see are the lines where playerMob (just a blank 3d cube) and attachedController are referenced to. As far as I can tell, they don't seem to be saving to the defined variable, but in lines 32 & 33 there are no errors so it seems it's just saving to a temporary, that-function-only variable rather than the class variable (The "Human" prefab is made successfully).

I feel as though I've made a simple yet fundamental mistake, yet I can't for the life of me wrap my head around what it could be.

I've tried removing the monobehaviour inheritance from player and using the new() keyword instead of Instantiating it, but the same thing happens. What did I do wrong?

EDIT: Here's a little test I made.

using UnityEngine;
using System.Collections;

public class Client : MonoBehaviour {

string username;
Player player;
GameObject playerMob;
ClientController clientController;

// Use this for initialization
void Start () {
    clientController = gameObject.GetComponent( typeof(ClientController) ) as ClientController;
    if(clientController == null){
        Debug.LogWarning("Client Controller is null!");
    } else {
        Debug.LogWarning ("Client Controller is NOT null!");
    }
}

// Update is called once per frame
void Update () {

}

public void FinishCharacterCreation(){
    player = new Player ();
    if (player == null) {
        Debug.LogWarning ("Player is null!");
    } else {
        Debug.LogWarning ("Player is NOT null!");
        playerMob = Instantiate (Resources.Load ("Human", typeof(GameObject))) as GameObject;
    }
    if (playerMob == null) {
        Debug.LogWarning ("PlayerMob is null!");
    } else {
        Debug.LogWarning ("PlayerMob is NOT null!");
    }
    if (clientController == null) {
        Debug.LogWarning ("ClientController is null!");
    } else {
        Debug.LogWarning ("ClientController is NOT null!");
    }

}

}

Debug log warnings everywhere. What I get when this is played is:

Client Controller is NOT null!
Player is NOT null!
PlayerMob is NOT null!
ClientController is null!

Notice the final log. Why is that happening? FinishCharacterCreation() is obviously being called after the clientController variable is set. All scripts and objects are completely empty aside from the one you see there. (Player does not inherent from monobehaviour, ClientController does) FinishCharacterCreation() is called by a UI button, and the Client attached GameObject is a prefab made from the base NetworkManager object.

  • 4
    You're accessing an object that is not instantiated. You need to review your references and figure out what is being called first. Make sure you are instantiating before all possible uses of an object. For example, if `MovementInput(float x, float y, float z)` is called before your `FinishCharacterCreation()` method, it will throw a null reference because `playerMob` is null... Review this post: http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it – Mikanikal Jul 07 '16 at 12:40
  • 1
    I recommend you to subscribe here and watch the beginner series (along with Unity beginner training) https://www.youtube.com/user/Cercopithecan/videos –  Jul 07 '16 at 12:46
  • The playerMob is not used at all before FinishCharacterCreation (I know for certain because the error does not come up before that is called) and as you can tell from the code ClientController is attached to the same GameObject as PlayerClient is, so shouldn't one be Instantiated if the other is? MovementInput() is called by ClientController which is not enabled until after FinishCharacterCreation() – GrimdeReaper Jul 07 '16 at 13:31

1 Answers1

0

When does FinishCharacterCreation get called? It's possible that FinishCharacterCreation gets called before Start which would result in attachedController being null. When the gameObject is instantiated it may take a frame or two for Start to get called so it's possible that you are calling FinishCharacterCreation prematurely. I would put some Debug.Logs in and make sure that all your functions are being called in the order you expect them to.

Cabby
  • 11
  • 1