1

I read this explanation of NullReferenceException in C# but couldn't find an answer.

I'm working in Unity5 (2D) and trying to make a button that, when clicked, activates a method in the script of another object.

In the classes, I added comments like //(line #) so you can reference from the NRE easier.

public class runePadController : MonoBehaviour {
public void shoot() {
    var fccClass = new friendlyCastleController();
    fccClass.shoot(); //(Line 23)
}
}

The button activates the shoot() method in the above class.

public class friendlyCastleController : MonoBehaviour {
public void shoot() {
    useElement (true, "fireBall"); //(Line 36)
}

public void useElement (bool atk, string type)
{
    switch (type)
    {
        case "fireBall":
            if (atk)
            {
                //Object clone;
                Vector3 nPosition = new Vector3();
                float nX = transform.position.x + Random.Range(-5F, 5F); //(Line 48)
                float nY = transform.position.y + 3F;
                nPosition.Set(nX, nY, 0);

                Quaternion nAngle = new Quaternion();
                nAngle.Set(Random.Range(-0.15F, 0.15F), 1, 0, 0);
                //Debug.Log(nPosition + " :: " + nAngle);

                //clone = (Instantiate(fireBallPF, nPosition, nAngle)) as GameObject;
                Instantiate(fireBallPF, nPosition, nAngle);
            }
            else
            {

            }

            break;
        default:
           Debug.Log ("Error: Default Switch Called in FriendlyCastleController");
            break;
    }
}

...and this is part of the class which deals with the called method.

However, Unity throws this at me:

NullReferenceException
friendlyCastleController.useElement (Boolean atk, System.String type) (at Assets/Scripts/friendlyCastleController.cs:48)
friendlyCastleController.shoot () (at Assets/Scripts/friendlyCastleController.cs:36)
runePadController.shoot () (at Assets/Scripts/runePadController.cs:23)
UnityEngine.Events.InvokableCall.Invoke (System.Object[] args) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:144)
UnityEngine.Events.InvokableCallList.Invoke (System.Object[] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:621)
UnityEngine.Events.UnityEventBase.Invoke (System.Object[] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:756)
UnityEngine.Events.UnityEvent.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:53)
UnityEngine.UI.Button.Press () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:35)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:44)
UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:52)
UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:269)
UnityEngine.EventSystems.EventSystem:Update()

To anyone who understands this better, can you point me in the right direction?

Thanks! :)

Community
  • 1
  • 1
  • 1
    we dont know, where is line 48 – Jacek Cz May 22 '16 at 12:56
  • Presumably either `transform` is null or `transform.position` is null. – Jon Skeet May 22 '16 at 12:57
  • It says where line 48 is. Look in the code of the second class. :) – SolarSupremacy May 22 '16 at 12:57
  • Also, when the method is run within it's own class, it works fine. No idea why the transform would be null. – SolarSupremacy May 22 '16 at 12:58
  • this is completely wrong: friendlyCastleController. It must be FriendlyCastleController. Same for your other class names. – Fattie May 22 '16 at 13:25
  • "var fccClass = new FriendlyCastleController();" You would not call the variable "fccClass". (Would a parent name their child "John" or "JohnPerson" ?) the variable name would typically be simply friendlyCastleController (identical to the class name, but, with lower-case first letter). You need to change all this. – Fattie May 22 '16 at 13:26

1 Answers1

2

Try assigning the friendlyCastleController class to the gameObject from where you are taking transform.position values, and in runePadController instead for creating a new friendlyCastleController use,

var fccClass = gameObjectName.getComponent<friendlyCastleController>();

OP, everything you are doing is completely wrong:

This statement

 var fccClass = new FriendlyCastleController();

is completely meaningless and does not exist in Unity. Unity is not an OO system, it is an ECS system. There is no inheritance nor any OO concepts whatsoever. This line

 public class FriendlyCastleController:MonoBehaviour

means that FriendlyCastleController is a MonoBehavior. What does that mean? It means it is a component you attach to an actual specific GameObject.

It can not exist on its own, it can only exist as an attachment to a game object.

  1. in the editor make a new game object (perhaps a small cube for example) called AAA

  2. actually attach a FriendlyCastleController script to that object

  3. make a new script called Test.cs, also a monobehavior, and attach Test.cs to some other object called BBB

  4. In Test.cs, do this

      public FriendlyCastleController friendlyCastle;
    
  5. Now LOOK in the Editor at BBB. Notice you can actually drag to the slot "friendlyCastle". Do that - in fact drag from AAA.

Now you understand how Unity works.

in RunePadController you must have a

      public FriendlyCastleController friendlyCastle;

and you drag your "AAA" object (in the example here) to that. Later, you can learn how to "Find" the "AAA" object on the fly inside RunePadController.

Fattie
  • 30,632
  • 54
  • 336
  • 607
CloudSL
  • 346
  • 1
  • 10
  • 1
    Indeed. I will expand on your answer. – Fattie May 22 '16 at 13:27
  • @JoeBlow Thank you for the thorough explanation sir. – CloudSL May 22 '16 at 13:45
  • I entered "public FriendlyCastleController friendlyCastle;" in to the RunePadController, and it seems to already know the class. I can't select it in Unity, but that may be because of an error. You said "gameObjectName" at the top of your answer, so I assume it is meant to be the the friendlyCastle object, the physical object in Unity with the class attached to it. However, it says "FriendlyCastleController does not contain a definition for 'getComponent' and no extension method 'getComponent' in "var fccClass = friendlyCastle.getComponent();". – SolarSupremacy May 22 '16 at 14:31
  • Have you assigned the RunePadController to a gameObject, if so check that gameObject's inspector view, you will see a place by the name `friendly Castle` where you can drag and drop the physical Object (Gameobject which contain the `FriendlyCastleController`) on to. doing so now you do not need to use `var fccClass = friendlyCastle.getComponent();` you can remove that line of code and directly use friendlyCastle variable in the place of fccClass as `friendlyCastle.shoot();` – CloudSL May 22 '16 at 14:48
  • Please tick as correct if this was to answer you expected. – CloudSL May 25 '16 at 05:56