1. 在Unity中比较常见的功能发射子弹,一般得我们都去动态生成物体(子弹prefab).
- 动态生成物体优点:1.可以灵活的控制场景 2. 可以马上看到效果.
- 缺点:这样不断的生成,销毁,性能开销大.
2. 所以一般我们使用Cache 缓存来完成. 上代码.
3. 首先创建一个脚本,巢穴吧.
public class DbSpawn : MonoBehaviour { public static DbSpawn Instance; public ObjectCache[] Caches; private Hashtable _cacheObjects; [System.Serializable] public class ObjectCache { public GameObject Prefab; public int CacheLens = 10; private GameObject[] _objects; private int cacheIndex = 0; /// <summary> /// 初始化 /// </summary> public void Init() { _objects = new GameObject[CacheLens]; for (int i = 0; i < CacheLens; i++) { _objects[i] = Instantiate(Prefab) as GameObject; _objects[i].gameObject.SetActive(false); _objects[i].name = _objects[i].name + i; } } /// <summary> /// 获取没有被激活的 /// </summary> /// <returns></returns> public GameObject GetNextObjectCache() { GameObject obj = null; for (int i = 0; i < CacheLens; i++) { obj = _objects[cacheIndex]; if (!obj.activeSelf) { break; } cacheIndex = (cacheIndex + 1) % CacheLens; } if (obj != null && obj.activeSelf) { DbSpawn.Destroy(obj); } cacheIndex = (cacheIndex + 1) % CacheLens; return obj; } } void Awake() { Instance = this; var total = 0; foreach (ObjectCache t in Caches) { t.Init(); total += t.CacheLens; } _cacheObjects = new Hashtable(total); } /// <summary> /// 孵化一个prefab实例 /// </summary> /// <param name="prefab"></param> /// <param name="position"></param> /// <param name="rotation"></param> /// <returns></returns> public static GameObject SpawnObject(GameObject prefab, Vector3 position, Quaternion rotation) { ObjectCache cache = null; if (Instance) { //获取符合当前prefab缓存 foreach (ObjectCache t in Instance.Caches) { if (t.Prefab == prefab) { cache = t; break; } } } if (cache == null) { return Instantiate(prefab, position, rotation) as GameObject; } //获取当前缓存容器 可用实例 GameObject obj = cache.GetNextObjectCache(); //设置实例属性 obj.transform.position = position; obj.transform.rotation = rotation; obj.SetActive(true); //存入哈希表 Instance._cacheObjects[obj] = true; return obj; } //销毁处理 public static void Destroy(GameObject obj) { if (Instance && Instance._cacheObjects.ContainsKey(obj)) { obj.SetActive(false); Instance._cacheObjects[obj] = false; } else { Destroy(obj); } }
4. 在子弹prefab创建一个脚本
public class DbBullet : MonoBehaviour { /// <summary> /// 速度 /// </summary> public float Speed = 10f; /// <summary> /// 子弹生命时间 /// </summary> public float Life = 0.5f; /// <summary> /// 距离 /// </summary> public float Dist = 1000; private float _spawnTime = 0f; private Transform _tr; void OnEnable() { _tr = transform; _spawnTime = Time.deltaTime; } // Update is called once per frame void Update() { _tr.position += transform.forward * Speed * Time.deltaTime; Dist -= Speed * Time.deltaTime; if (Time.deltaTime > _spawnTime + Life || Dist < 0) { DbSpawn.Destroy(gameObject); Dist = 10; } }
5. 模拟发射了.
public class DbShooter : MonoBehaviour { public Transform point; public GameObject prefab; public float TimeCount = 10f; private float _timer = 0f; private bool _isShooter = false; // Update is called once per frame void Update() { if (Input.GetMouseButtonDown(0)) { _isShooter = true; } if (Input.GetMouseButtonUp(0)) { _isShooter = false; } if (_isShooter) { _timer += Time.deltaTime; if (_timer > 1 / TimeCount) { DbSpawn.SpawnObject(prefab, point.position, Quaternion.identity); _timer = 0f; } } } }
- - 我也是初学者,小白,分享一下,同时自己也加深印象3Q..
时间: 2024-10-29 19:05:36