1

help me please I'm doing an assignment and I'm having trouble with my code I'm trying to have an instance of weaponStats that I can reference back for stats on weapons and in the gameManager it changes weaponID to the current equipped weapon on the player but when i try to hit an enemy unity says that stats is = to null

On the line "if (stats.weaponID == 1)" I receive a null reference error I've tried a number of different ways to instantiate but still get the null error

yet i don't receive an error in other classes

please see the function below

    public void Shoot(bool isTesting = false)
{
    Vector2 mousePosition = new Vector2(Camera.main.ScreenToWorldPoint(Input.mousePosition).x, Camera.main.ScreenToWorldPoint(Input.mousePosition).y);
    Vector2 firePointPosition = new Vector2(firePoint.position.x, firePoint.position.y);
    Vector2 direction = mousePosition - firePointPosition;
    if (isTesting)
    {
        direction = transform.right;
    }
    RaycastHit2D hit = Physics2D.Raycast(firePointPosition, direction, 100, whatToHit.value);

    // kill the enemy nothing else and check what weapon it was
    if (hit.collider != null) {
        Enemy enemy = hit.collider.GetComponent<Enemy>();
        if (enemy != null) {

            if (stats == null)
            {
                stats = WeaponStats.instance;
            }

            if (stats.weaponID == 1)
            {
                enemy.Damaged(stats._PistolDamage);
            }
            else if (stats.weaponID == 2)
            {
                enemy.Damaged(stats._RifleDamage);
            }
            else {

                Debug.Log("HELP!!");

            }

        }
    }

    // spawn effects
    if (Time.time >= timeToSpawnEffect) {
        Vector3 hitPos;
        Vector3 hitNormal;

        if (hit.collider == null) {
            hitPos = direction * 35;
            hitNormal = new Vector3(9999, 9999, 9999);
        } else {
            hitPos = hit.point;
            hitNormal = hit.normal;
        }

        Effect(hitPos, hitNormal);
        timeToSpawnEffect = Time.time + 1 / effectSpawnRate;
    }
}

This is a copy of the weaponstats class

using UnityEngine;
using System.Collections;

public class WeaponStats : MonoBehaviour {

    public static WeaponStats instance;

    public int weaponID = 0;

    // dmage based on equiped weapon
    public float Damage = 10f;
    public float Firerate = 7.5f;

    #region Weapons

        #region Pistol
        public float _PistolDamage = 30f;
        public float _PistolFirerate = 0f;
        #endregion

        #region Rifle
        public float _RifleDamage = 10f;
        public float _RifleFirerate = 7.5f;
        #endregion

    #endregion

    /// <summary>
    /// if weapon stats instance = to null
    /// </summary>
    void Awake() {
        if (instance == null) {
            instance = this;
        }
    }
}

In this script it works perfectly fine

using UnityEngine;

using UnityEngine.UI;

public class WeaponUpgrading : WeaponStats {

// weapons text fields
#region Pistol
[SerializeField]
private Text PistolDamage;

[SerializeField]
private Text PistolFirerate;
#endregion
#region Rifle
[SerializeField]
private Text RifleDamage;

[SerializeField]
private Text RifleFirerate;
#endregion

#region Modifires
[SerializeField]
private float DamageMultiplier = 1.3f;

[SerializeField]
private float FirerateMultiplier = 1.3f;
#endregion

private WeaponStats stats;

void Start() {

    stats = WeaponStats.instance;
    UpdateValues(0); // update all on load

}

void UpdateValues(int ID) {

    switch (ID) {

        case 1:
            // update pistol
            PistolDamage.text = "Damage: " + stats._PistolDamage.ToString();
            PistolFirerate.text = "Firerate: " + stats._PistolFirerate.ToString();

            break;

        case 2:
            // update rifle
            RifleDamage.text = "Damage: " + stats._RifleDamage.ToString();
            RifleFirerate.text = "Firerate: " + stats._RifleFirerate.ToString();

            break;

        default:
            // refresh all on default
            PistolDamage.text = "Damage: " + stats._PistolDamage.ToString();
            PistolFirerate.text = "Firerate: " + stats._PistolFirerate.ToString();

            RifleDamage.text = "Damage: " + stats._RifleDamage.ToString();
            RifleFirerate.text = "Firerate: " + stats._RifleFirerate.ToString();

            break;

    }  

}

public void UpgradePistol() 
    {

    //Debug.Log(s)
    /*
    stats.PistolDamage = (stats.PistolDamage * DamageMultiplier);
    stats.PistolFirerate = Mathf.Round(stats.PistolFirerate * FirerateMultiplier);

    UpdateValues(1);
    */

    stats._PistolDamage = stats._PistolDamage * DamageMultiplier;
    PistolDamage.text = "" + stats._PistolDamage;

}

public void UpgradeRifle() {


    stats._RifleDamage = stats._RifleDamage * DamageMultiplier;
    RifleDamage.text = "" + stats._RifleDamage;

    stats._RifleDamage = stats._RifleDamage * DamageMultiplier;
    RifleDamage.text = "" + stats._RifleFirerate * FirerateMultiplier;

    /*
    stats.RifleDamage = (int)(stats.RifleDamage * DamageMultiplier);
    stats.RifleFirerate = Mathf.Round(stats.RifleFirerate * FirerateMultiplier);
    */
    //UpdateValues(2);
}

}

Razzel
  • 13
  • 4
  • `stats = WeaponStats.instance;` Basically, this exception occurs because `stats = WeaponStats.instance` is null. You need to fix that. – mjwills Jun 17 '17 at 09:53
  • If you want instance of `WeaponStats` to exist, you at least need to attach `WeaponStats` to one GameObject. Just create an empty GameObject and attach `WeaponStats` to it. That's all. – Programmer Jun 17 '17 at 09:56

1 Answers1

2

Reason you still get a NullReferenceException for stats = WeaponStats.instance is because no where you actually initialize WeaponStats.instance. having it as a static member of the class does not initialize it. The only place you access it is in the Awake method which is not being called.

It might be that it is worth having a look at the Singelton design pattern - it seems like you are trying to do something similar to it.

Look here for dofactory.com on Singelton

Graham
  • 7,431
  • 18
  • 59
  • 84
Gilad Green
  • 36,708
  • 7
  • 61
  • 95
  • in another script it works fine when i upgrade the weapon damages though so its being called i dont know why its just that script – Razzel Jun 17 '17 at 09:56
  • @Razzel - might be that somewhere else it works but in the given code you do not initialize it anywhere - hence the error – Gilad Green Jun 17 '17 at 09:57
  • i placed more code into my question because they both do the exact same thing i tried to instantiate it in the broken script but it had no effect. i did a debug on it and it sees the variables but the stats base is null for some reason – Razzel Jun 17 '17 at 10:04
  • @Razzel - added code does not help solving it. There too you use `Start` to assign a value to the variable but do not show where you actually call the `Start`. But in any case problem is that you do not initialize your variable before using it. If you initialize it through a helper function you must make sure the function is called first – Gilad Green Jun 17 '17 at 10:08
  • OMG!!! IM AN IDIOT!!! thanks a lot man :D I was instancing nothing xDDD – Razzel Jun 17 '17 at 10:17
  • I kept trying to call a reference to a thing that wasn't there – Razzel Jun 17 '17 at 10:17