对应对象池个概念,网上有很多,而且关于在unity里面使用对象池的文章也很多,我这里就直接上代码好了:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Gun : MonoBehaviour {
public string weaponName;
/// <summary>
/// 子弹数列
/// </summary>
private List<BullectOfWeapon> weapons;
/// <summary>
/// 一个弹夹的子弹数量
/// </summary>
public int shellCount = 20;
/// <summary>
/// 预加载子弹数量,因为可以循环利用,可以是小于等于弹夹的子弹数量
/// </summary>
public int maxShell = 0;
/// <summary>
/// 冷却时间
/// </summary>
public float fireRote = 0.2f;
/// <summary>
/// 当前时间
/// </summary>
private float currentFireTime;
/// <summary>
/// 用完一个弹夹后,换弹夹的时间
/// </summary>
public float loadTime = 1.5f;
private float currentLoadTime = 0;
/// <summary>
/// 一个弹夹打出去的子弹数量
/// </summary>
private int currentCount;
/// <summary>
/// 弹夹数量
/// </summary>
public int chargerCount = 5;
public int currentShell;
void Start()
{
InitGun();
}
void Update()
{
if(!isLoading()&&checkFire()&&Input .GetButton ("Fire1"))
{
Shot();
}
}
private void InitGun()
{
BullectOfWeapon weaponModel = Resources.Load<BullectOfWeapon>(weaponName);
if(weaponModel)
{
weapons = new List<BullectOfWeapon>();
for (int i = 0; i < maxShell ; i++)
{
BullectOfWeapon weapon = Instantiate(weaponModel);
weapon.gameObject.SetActive(false);
//初始化子弹的相关信息
weapon.InitWeapon(transform);
weapons.Add(weapon);
}
}
//释放资源
weaponModel = null;
}
/// <summary>
/// 判断子弹用完,是否上弹完毕
/// </summary>
/// <returns></returns>
private bool isLoading()
{
if (chargerCount == 0) return true;
if(currentCount <shellCount )
{
return false;
}
currentLoadTime += Time.deltaTime;
if(currentLoadTime >=loadTime )
{
currentLoadTime = 0;
chargerCount--;
currentCount = 0;
return false;
}
return true;
}
/// <summary>
/// 是否可以开火
/// </summary>
/// <returns></returns>
public bool checkFire()
{
currentFireTime += Time.deltaTime;
if(currentFireTime >=fireRote )
{
currentFireTime = 0;
return true;
}
return false;
}
/// <summary>
/// 开火
/// </summary>
private void Shot()
{
if(weapons !=null &&weapons .Count >0)
{
if(!weapons [currentShell ].gameObject .activeSelf )
{
//激活子弹,执行使用的逻辑
weapons[currentShell].ActiveWeapon();
currentShell = (currentShell + 1) % maxShell;
currentCount++;
}
}
}
}
using UnityEngine;
using System.Collections;
public class BullectOfWeapon : MonoBehaviour {
private Transform charger;
public float lifeTime = 3;
public float maxSpeed;
/// <summary>
/// 子弹实时速度
/// </summary>
private Vector3 velocity;
/// <summary>
/// 子弹当前位置
/// </summary>
private Vector3 currentPos;
private Vector3 nextPos;
private bool isHit;
private float distance;
private RaycastHit hit;
/// <summary>
/// 设置子弹的父类以及位置等待信息
/// </summary>
/// <param name="parent"></param>
public void InitWeapon(Transform parent)
{
if (!charger) this.charger = parent;
transform.parent = charger;
transform.localPosition = Vector3.zero;
transform.localRotation = Quaternion.identity;
}
public void ActiveWeapon()
{
//初始化子弹位置
currentPos = nextPos = transform.position;
isHit = false;
//速度
velocity = maxSpeed * transform.forward.normalized;
transform.parent = null;
gameObject.SetActive(true);
//开启协程,lifetime之后再次隐藏
StartCoroutine(DestroyWeapon(gameObject, lifeTime));
}
private IEnumerator DestroyWeapon(GameObject obj,float desTime)
{
yield return new WaitForSeconds(desTime > 0 ? desTime : 0);
if(obj .activeSelf )
{
obj.SetActive(false);
InitWeapon(charger);
}
}
void Update()
{
//Fire();
}
private void Flying()
{
nextPos += velocity * Time.deltaTime;
distance = (nextPos - currentPos).magnitude;
if(distance >0)
{
if(Physics .Raycast (currentPos ,transform .forward ,out hit,distance ))
{
isHit = true;
nextPos = hit.point;
}
}
currentPos = transform.position;
transform.position = nextPos;
if(isHit )
{
StartCoroutine(DestroyWeapon(gameObject, 0));
}
}
}