0
votes

So I have a character who is able to shoot however when the character dies and respawns he is unable to shoot and i get the error: UnassignedReferenceException: The variable BulletTrailPrefab of Weapon has not been assigned.

You probably need to assign the BulletTrailPrefab variable of the Weapon script in the inspector.

UnityEngine.Object.Internal_InstantiateSingle (UnityEngine.Object data, Vector3 pos, Quaternion rot) (at C:/BuildAgent/work/d63dfc6385190b60/artifacts/EditorGenerated/UnityEngineObject.cs:74)

UnityEngine.Object.Instantiate (UnityEngine.Object original, Vector3 position, Quaternion rotation) (at C:/BuildAgent/work/d63dfc6385190b60/artifacts/EditorGenerated/UnityEngineObject.cs:84)

Weapon.Effect () (at Assets/Weapon.cs:64)

Weapon.Shoot () (at Assets/Weapon.cs:53)

Weapon.Update () (at Assets/Weapon.cs:33)

So if someone can help me fixing this it would be greatly appreciated. I have tried lots of stuff however nothing appears to work :(

My weapon script

using UnityEngine; using System.Collections;

public class Weapon : MonoBehaviour {

public float fireRate = 0;
public float Damage = 10;
public LayerMask whatToHit;

public Transform target;

public Transform BulletTrailPrefab;
float timeToSpawnEffect = 0;
public float effectSpawnRate = 10;

float timeToFire = 0;
Transform firePoint;

float nextTimeToSearch = 0;

// Use this for initialization
void Awake () {
    firePoint = transform.FindChild ("firePoint");
    if (firePoint == null) {
        Debug.LogError ("No firePoint? WHAT?!");
    }
}

// Update is called once per frame
void Update () {
    if (fireRate == 0) {
        if (Input.GetButtonDown ("Fire1")) {
            Shoot();
        }
    }
    else {
        if (Input.GetButton ("Fire1") && Time.time > timeToFire) {
            timeToFire = Time.time + 1/fireRate;
            Shoot();
        }
    }
    if (target == null) {
        FindBulletTrailPrefab ();
        return;
    }
}

void Shoot () {
    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);
    RaycastHit2D hit = Physics2D.Raycast (firePointPosition, mousePosition-firePointPosition, 100, whatToHit);
    if (Time.time >= timeToSpawnEffect) {
        Effect ();
        timeToSpawnEffect = Time.time + 1/effectSpawnRate;
    }
    Debug.DrawLine (firePointPosition, (mousePosition-firePointPosition)*100, Color.cyan);
    if (hit.collider != null) {
        Debug.DrawLine (firePointPosition, hit.point, Color.red);
        Debug.Log ("We hit " + hit.collider.name + " and did " + Damage + " damage.");
    }
}

void Effect () {
    Instantiate (BulletTrailPrefab, firePoint.position, firePoint.rotation);
}
void FindBulletTrailPrefab () {
    if (nextTimeToSearch <= Time.time) {
        GameObject searchResult = GameObject.FindGameObjectWithTag ("BulletTrail");
        if (searchResult != null)
            target = searchResult.transform;
        nextTimeToSearch = Time.time + 0.5f;
    }
}

}

My gamemaster script

using UnityEngine;
using System.Collections;

public class GameMaster : MonoBehaviour {

    public static GameMaster gm;

    void Start () {
        if (gm == null) {
            gm = GameObject.FindGameObjectWithTag ("GM").GetComponent<GameMaster>();
        }
    }

    public Transform playerPrefab;
    public Transform spawnPoint;
    public int spawnDelay = 2;

    public IEnumerator RespawnPlayer () {
        Debug.Log ("TODO: Add waiting for spawn sound");
        yield return new WaitForSeconds (spawnDelay);

        Instantiate (playerPrefab, spawnPoint.position, spawnPoint.rotation);
        Debug.Log ("TODO: Add Spawn Particles");
    }

    public static void KillPlayer (Player player) {
        Destroy (player.gameObject);
        gm.StartCoroutine (gm.RespawnPlayer());
    }
}

My player script

using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour {

    [System.Serializable]
    public class PlayerStats {
        public int Health = 100;
    }

    public PlayerStats playerStats = new PlayerStats();

    public int fallBoundary = -20;

    void Update () {
        if (transform.position.y <= fallBoundary)
            DamagePlayer (9999999);
    }

    public void DamagePlayer (int damage) {
        playerStats.Health -= damage;
        if (playerStats.Health <= 0) {
            GameMaster.KillPlayer(this);
        }
    }
}
2

2 Answers

0
votes

The error is quite clear. You have not assigned a prefab to your variable..

UnassignedReferenceException: The variable BulletTrailPrefab of Weapon has not been assigned.

You probably need to assign the BulletTrailPrefab variable of the Weapon script in the inspector.

0
votes

Late answer for answering's sake! (Lovely!)

The reason it only happens after you respawn is because when you instantiate a new playerPrefab, the Weapon object (which presumably is part of your player prefab) does not have the assignments you had made in the editor—those assignments are only for the specific instances that were in the editor. You'll need to manually assign it at runtime in one of two ways:

1) When you respawn:

public IEnumerator RespawnPlayer () {
    // ...
    GameObject playerInstance = Instantiate (
        playerPrefab,
        spawnPoint.position,
        spawnPoint.rotation) as GameObject;
    Weapon weaponInstance = playerInstance.GetComponentInChildren<Weapon>;
    weaponInstance.BulletTrailPrefab = /* prefab reference */;
    // ...
}

2) In your Weapon script:

void Start () {
    BulletTrailPrefab = /* prefab reference */;
}

But in either case you would have to have some way of referencing the prefab at runtime, such as putting a reference into the GameMaster script or using Resources.Load().