在创建我的塔防游戏的过程中,我偶然发现了基于塔类的精灵渲染问题(因此一次加载了两种不同类型的塔)。我的问题基本上是如何以安全的方式加载这些精灵,我可以从中创建多个塔类。
我有两个塔式预制件,例如,我的游戏控制器脚本中的塔式每个都是FIRST_TOWER或SECOND_TOWER(我有游戏控制器和塔式脚本)。
public enum TowerType
{
FIRST_TOWER,
SECOND_TOWER
}
我试图在游戏开始时使用以下方法为不同的塔类加载主精灵:
private void Start(){
AllTowers.Add (new Tower (2, 3f, "TowerSprites/FTower"));
AllTowers.Add (new Tower (5, 1, "TowerSprites/STower"));
}
我的Tower脚本中提到了AllTowers,而TowerSprites是资源资源中的文件夹(FTower和STower是两个不同类别的塔楼)。
private void Start()
{
gcs = FindObjectOfType<GameControllerScr>();
selfTower = gcs.AllTowers[(int)selfType]; // Unity error leads here
GetComponent<SpriteRenderer> ().sprite = selfTower.Spr;
}
此外,unity还提到了一个NullReferenceException:对象引用未设置为selfTower行中的对象实例。
以及其他方法,包括Cooldown(可以工作)和加载精灵
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);
}
}
问题是,sprite不会从我的资源文件加载,我希望它在游戏开始时加载,因为我想在商店中实现不同的塔类我会稍后放入我的游戏。我怎么能这样做?
(PS:没有编译器错误)
我添加了我的游戏控制器和塔式脚本的完整脚本,以便发现可能影响它的其他一些问题。
我对团结和编码都很陌生......但我想从错误中吸取教训,谢谢。
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);
}
}
完整游戏控制器脚本
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"));
}
}