I have the next error: NullReferenceException: Object Reference not set to an instance of object. It happen when I click a button for buy a object in the game. You can see it in the next image:
But I have some doubts when implementing the code, for example. My code is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class TradeCupcakeTowers_Buying : TradeCupcakeTowers {
// Public variable to identify wich tower this script is selling.
// Ideally, you could have many instances of this script seling different cupcake towers,
// and the tower is specified in the Inspector.
public GameObject cupcakeTowerPrefab;
public override void OnPointerClick(PointerEventData eventData)
{
//Retrieve form the prefab which is its initial cost
int price = cupcakeTowerPrefab.GetComponent<CupcakeTowerScript>().initialCost;
// check if the player can afford to buy the tower
if (price <= sugarMeter.getSugarAmount())
{
// Payment success, and the cost is removed from the player's sugar
sugarMeter.ChangeSuger(-price);
// A new cupcake tower is created
GameObject newTower = Instantiate(cupcakeTowerPrefab);
// The new cupcake tower is also assigned as the current selection
currentActiveTower = newTower.GetComponent<CupcakeTowerScript>();
}
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
But, Visual Studio advises me to change my code in public override void OnPointerClick(PointerEventData eventData), calling a new method. In this new method perform the purchase actions. You can see it below:
public override void OnPointerClick(PointerEventData eventData)
{
//Retrieve form the prefab which is its initial cost
int price = cupcakeTowerPrefab.GetComponent<CupcakeTowerScript>().initialCost;
// check if the player can afford to buy the tower
NewMethod(price);
}
private void NewMethod(int price)
{
if (price <= sugarMeter.getSugarAmount())
{
// Payment success, and the cost is removed from the player's sugar
sugarMeter.ChangeSuger(-price);
// A new cupcake tower is created
GameObject newTower = Instantiate(cupcakeTowerPrefab);
// The new cupcake tower is also assigned as the current selection
currentActiveTower = newTower.GetComponent<CupcakeTowerScript>();
}
}
In any case, the error mentioned at the beginning persists.
So, does the console tell you on which line the error occurs? If so, did you check that line of code & then try to figure out which âpossibleâ variable was null (if there is more than one)?
First, when I apply the changes suggest by Visual Studio:
this is:
public override void OnPointerClick(PointerEventData eventData)
{
//Retrieve form the prefab which is its initial cost
int price = cupcakeTowerPrefab.GetComponent<CupcakeTowerScript>().initialCost;
// check if the player can afford to buy the tower
NewMethod(price);
}
private void NewMethod(int price)
{
NewMethod1(price);
}
private void NewMethod1(int price)
{
if (price <= sugarMeter.getSugarAmount())
{
// Payment success, and the cost is removed from the player's sugar
sugarMeter.ChangeSuger(-price);
// A new cupcake tower is created
GameObject newTower = Instantiate(cupcakeTowerPrefab);
// The new cupcake tower is also assigned as the current selection
currentActiveTower = newTower.GetComponent<CupcakeTowerScript>();
}
}
Now, I play the game and it show the next:
NullReferenceException: Object reference not set to an instance of an object
TradeCupcakeTowers_Buying.NewMethod1 (Int32 price) (at Assets/Scripts/UI_Scripts/TradeCupcakeTowers_Buying.cs:29)
TradeCupcakeTowers_Buying.NewMethod (Int32 price) (at Assets/Scripts/UI_Scripts/TradeCupcakeTowers_Buying.cs:24)
TradeCupcakeTowers_Buying.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at Assets/Scripts/UI_Scripts/TradeCupcakeTowers_Buying.cs:19)
UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:50)
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:261)
UnityEngine.EventSystems.EventSystem:Update()
Right, Iâm not sure to which line that is referring because your postâs lines do not match the lines from the error (on my end). Did you try to look at the line and see what could possibly be null?
public override void OnPointerClick(PointerEventData eventData)
{
//Retrieve form the prefab which is its initial cost
int price = cupcakeTowerPrefab.GetComponent<CupcakeTowerScript>().initialCost;
Debug.Log("Error1: " + price);
// check if the player can afford to buy the tower
if (price <= sugarMeter.getSugarAmount())
{
Debug.Log("Error2: " + sugarMeter.getSugarAmount());
// Payment success, and the cost is removed from the player's sugar
sugarMeter.ChangeSuger(-price);
// A new cupcake tower is created
GameObject newTower = Instantiate(cupcakeTowerPrefab);
// The new cupcake tower is also assigned as the current selection
currentActiveTower = newTower.GetComponent<CupcakeTowerScript>();
}
else {
Debug.Log("here!");
}
}
var price return value, but sugarMeter.getSugarAmount() notâŠ
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Sugar_meterScript : MonoBehaviour {
private Text sugarMeter; // Referencia la componente de texto
private int sugar; // Cantidad de azucar que el player posee
// Use this for initialization
void Start () {
// Get the reference to the Sugar_Meter_Text
sugarMeter = GetComponentInChildren<Text>();
// Update the sugar meter graphics
updateSugarMeter();
}
// Update is called once per frame
void Update () {
}
// FunciĂłn para incrementar o decrementar la cantidad de azĂșcar
public void ChangeSuger(int value) {
// Incrementa oa decrementa, si el valor es negativo, la cantidad de ĂĄzĂșcar
sugar += value;
// Checa si la cantidad de azucar es negativa, si es asĂ la establece en cero.
if (sugar < 0) {
sugar = 0;
}
// Update sugar meter graphic
updateSugarMeter();
}
// FunciĂłn para regresar la cantidad de azĂșcar
public int getSugarAmount() {
return sugar;
}
// funciĂłn para actualizar Sugar Meter graphic
void updateSugarMeter() {
// Assign the amount of sugar converted to a string to the text in the sugar meter
sugarMeter.text = sugar.ToString();
}
}
So, the fact that the text â1235â is not shown does not imply that it is not working correctly?
Okay, sometimes itâs hard to follow screenshots. I noticed your font size is 100 . Do you think you canât see it because it doesnât fit maybe? It should be showing that value in the inspector, while not playing, but when the game starts, it would probably say â0â , since you have not set any value (other than the default 0) to the âsugarâ.
This is what I was asking about â re: the sugarMeter variable from this snippet of your code:
// check if the player can afford to buy the tower
if (price <= sugarMeter.getSugarAmount())
{
Debug.Log("Error2: " + sugarMeter.getSugarAmount());
// Payment success, and the cost is removed from the player's sugar
sugarMeter.ChangeSuger(-price);
I thought you were telling me the error was around here? Please correct me if Iâve been mistaken about that for the last while. lol
Oh! Sorry, you donât wrong. My mistake is not explaining myself correctly, u.u
I use the text âErrorâ only as a info, only I try to get the value from sugarMeter.getSugarAmount() to know if price was doing the evaluation correctly in:
if (price <= sugarMeter.getSugarAmount())
Yep, I have the font in 100 pts because I was testing whether the number was visible or not. Its initial value is 14⊠Sorry for not correcting it before taking the screenshot u.u
the inspector show me the line 22 as the error. The line 22 is:
Right ,well I knew it was empty, I think b/c you said that was the null error
What Iâm trying to figure out is how were you assigning it? Perhaps you didnât assign it properly or perhaps not at all?
As for the text, try to adjust the rect transform size in the editor (like with the rect tool I mean⊠just drag it larger until you see the text.)
If the script in your first post is complete, post the TradeCupcakeTowers script (which is the base class of your TradeCupcakeTowers_Buying script). This is obviously responsible for resolving the instance of the sugarMeter (of type Sugar_meterScript).
Both are components, the sugarMeter is not exposed (no field for that in the TradeCupcakeTowersâ inspector) so it can only be resolved via codeâŠ
Now itâs interesting how that is done.
The screenshots show that the TradeCupcakeTower script resides on a GO which is a sibling to the parent of the GO which holds the sugar_meterScript componentâŠ
That is, if the TradeCupcakeTower script uses anything like GetComponent or GetComponentInChildren, youâre out of luck.
Instead, youâd either
search for the GO and get the component,
or you use FindObjectOfType
or use a singleton
OR the most straight-forward solution: expose the sugarMeter to the inspector and drag&drop it.
Hi Suddoha, it is the script for TradeCupcakeTowers:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public abstract class TradeCupcakeTowers : MonoBehaviour, IPointerClickHandler {
public abstract void OnPointerClick(PointerEventData eventData);
// Variable to store the Sugar Meter
protected static Sugar_meterScript sugarMeter;
// Variablo to store the current selected tower by the player
protected static CupcakeTowerScript currentActiveTower;
// Use this for initialization
void Start () {
// if the reference to the sugar meter is missing, the scripts get it
if (sugarMeter == null) {
sugarMeter = FindObjectOfType<Sugar_meterScript>();
}
}
// Update is called once per frame
void Update () {
}
// Static function that allows other scripts to assign the new/current selected tower
public static void setActivetower(CupcakeTowerScript cupcakeTower) {
currentActiveTower = cupcakeTower;
}
}
I guess, for what you say, the error is somewhere in the code, it has nothing to do with the inspector. Iâm reading the book again in case I forgot something âŠ
Oh okay, the code is fine and would normally work, but itâs a little detail that causes this behaviour:
Your base class (CupcakeTowerScript) uses Start (also Update) and theyâre declared as 1) private 2) non-virtual.
Your derived class (CupcakeTowerScript_Buying) uses Start (and also Update) as well.
Behind the scenes, Unity uses something called âReflectionâ to figure out these methods (Awake, Start, Update, FixedUpdate âŠ). What happens is, that Unity will find the Start method (also the Update one) of your derived type and calls this instead of Start of the base class, because thereâs no polymorphic behaviour due to missing virtual function calls.
The quick and probably easiest fix for now is, that you remove Start and Update from your Buying script. This helps Unity, it will now find the Start and Update method of the base class and can properly call into it.
If you want to implement further logic within the Buying scriptâs Start and Update method at a later time (provided you want to use these exact names) you will need the following: