3

During the progress of creating my Tower Defense game I stumbled upon a problem regarding to sprite rendering, based on a tower class (so two different types of towers being loaded at once). My question is basically how to load these sprites in a safe manner where I can make multiple tower classes from.

I have two tower prefabs, for example, with the TowerType of each being either FIRST_TOWER or SECOND_TOWER from my game controller Script (I have a game controller and tower script).

public enum TowerType
{
FIRST_TOWER,
SECOND_TOWER

}

I was trying to load a main sprite for different tower classes by using the following method when the game starts:

private void Start(){

AllTowers.Add (new Tower (2, 3f, "TowerSprites/FTower"));
AllTowers.Add (new Tower (5, 1, "TowerSprites/STower"));

}

with AllTowers being mentioned in my Tower script, and TowerSprites being the folder in Resources in Assets (FTower and STower are the two different towers with different classes).

private void Start()
{
gcs = FindObjectOfType<GameControllerScr>();

selfTower = gcs.AllTowers[(int)selfType]; // Unity error leads here
GetComponent<SpriteRenderer> ().sprite = selfTower.Spr;
}

Additionally, unity also mentions a NullReferenceException: Object reference not set to an instance of an object, in the selfTower line.

and also this other method including the Cooldown (which works) and loading the sprite

public class Tower // From Tower Defense
{

public float range, Cooldown, CurrCooldown = 0;
public Sprite Spr; 

public Tower(float range, float cd, string path)
{
    this.range = range;
    Cooldown = cd;
    Spr = Resources.Load<Sprite> (path);
}


}

The thing is, that the sprites won't load from my resources file, and I would like it to load at the beginning of the game, as there are different tower classes which I would like to implement in the shop I would put in my game later on. How can I do that?

(PS: There are no compiler errors)

I added the full script of my game controller and tower scripts, to maybe spot some other issue that might be affecting it.

I'm kind of new to unity, and coding in general... But I would like to learn from my mistakes, Thanks.

Full Tower Script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TowerScr : MonoBehaviour {

public GameObject Projectile;
Tower selfTower;
public TowerType selfType;
GameControllerScr gcs;

private void Start()
{
    gcs = FindObjectOfType<GameControllerScr>();

    selfTower = gcs.AllTowers[(int)selfType];
    GetComponent<SpriteRenderer> ().sprite = selfTower.Spr;
}

private void Update()
{
    if (CanShoot ())
        SearchTarget ();

    if (selfTower.CurrCooldown > 0)
        selfTower.CurrCooldown -= Time.deltaTime;
}

bool CanShoot()
{
    if (selfTower.CurrCooldown <= 0)
        return true;
    return false;
}

void SearchTarget()
{
    Transform nearestEnemy = null;
    float nearestEnemyDistance = Mathf.Infinity;

    foreach(GameObject enemy in GameObject.FindGameObjectsWithTag("Enemy")) 
    {
        float currDistance = Vector2.Distance (transform.position, enemy.transform.position);

        if (currDistance < nearestEnemyDistance &&
            currDistance <= selfTower.range) 
        {
            nearestEnemy = enemy.transform;
            nearestEnemyDistance = currDistance;
        }
    }

    if (nearestEnemy != null)
        Shoot (nearestEnemy);
}



void Shoot(Transform enemy)
{
    selfTower.CurrCooldown = selfTower.Cooldown;

    GameObject proj = Instantiate (Projectile);
    proj.GetComponent<TowerProjectileScr> ().selfProjectile = gcs.AllProjectiles [(int)selfType];
    proj.transform.position = transform.position;
    proj.GetComponent<TowerProjectileScr> ().SetTarget (enemy);
}


}

Full Game controller Script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class Tower // From Tower Defense
{

public float range, Cooldown, CurrCooldown = 0;
public Sprite Spr; 

public Tower(float range, float cd, string path)
{
    this.range = range;
    Cooldown = cd;
    Spr = Resources.Load<Sprite> (path);
}


}

public class TowerProjectile // separate gameobject with different Script
{
public float speed;
public int damage;
public Sprite Spr;

public TowerProjectile(float speed, int dmg, string path)
{
    this.speed = speed;
    damage = dmg;
    Spr = Resources.Load<Sprite>(path);
}


}

public enum TowerType
{
FIRST_TOWER,
SECOND_TOWER

}

public class GameControllerScr : MonoBehaviour {

public List<Tower> AllTowers = new List<Tower>();
public List<TowerProjectile> AllProjectiles = new List<TowerProjectile>();

private void Start()
{
    AllTowers.Add (new Tower (2, 3f, "TowerSprites/FTower"));
    AllTowers.Add (new Tower (5, 1, "TowerSprites/STower"));


    AllProjectiles.Add (new TowerProjectile (7, 10, "ProjectilesSprites/FProjectile"));
    AllProjectiles.Add(new TowerProjectile(3, 30, "ProjectilesSprites/SProjectile"));

}
}
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • `Resources.Load` is used to load data from the Resources folder. You have so many code and words in your question that I can no longer tell what exactly is the problem. Try a simple `Resources.Load("YourSpriteName")` and see if that returns null – Programmer Jan 09 '18 at 16:52

0 Answers0