利用对象池发射子弹(自创)
一:创建一个新的场景,随便创建一个物体,在这个物体上添加控制代码:控制这个物体前后左右,旋转方向。代码如下:
using UnityEngine;
using System.Collections;
//这是一个关于对象池的程序 ,发射20个子弹
public class DuiXiangCi : MonoBehaviour {
void Update () {
Control();
}
public void Control()
{
if (Input .GetKey(KeyCode.W))
{
this.transform.Translate(Vector3 .forward * 0.2f);
}
if (Input .GetKey(KeyCode.S))
{
this.transform.Translate(Vector3 .forward * -0.2f);
}
if (Input .GetKey(KeyCode.A))
{
this.transform.Rotate(Vector3 .up * -1.0f);
}
if (Input .GetKey(KeyCode.D))
{
this.transform.Rotate(Vector3 .up * 1.0f);
}
}
}
二: 按下鼠标左键, 这个物体开始发射子弹,隔几秒之后消失子弹,并且子弹发射方向随便物体旋转而改变方向。在这里,为了优化内存,我们用的是 对象池。挂在物体身上的代码如下:
using UnityEngine;
using System.Collections;
//这是一个关于对象池的程序 ,发射20个子弹
public class DuiXiangCi : MonoBehaviour {
public GameObject mFireBall; // 发射子弹的预设体
private Stack sFireBll = new Stack(); // 声名一个栈
public static DuiXiangCi dd;
public Transform MFirePos; // 开火位置
// Use this for initialization
void Start () {
Create(20);
dd = this;
}
public void Create(int num) //写一个发射20个子弹的循-环程序方法
{
for (int i = 0; i < num; i++)
{ // 声名一个实例化物体
GameObject obj = Instantiate(mFireBall) as GameObject;
obj.gameObject.SetActive( false); // 生成的这个物体刚开始的时候是不显示的
sFireBll.Push(obj); // 把这个生成的子弹放入栈中
}
}
// 出栈
GameObject GetObj(Vector3 pos, Quaternion rot)
{
if (sFireBll.Count < 2)
{
Create(10);
}
GameObject obj = sFireBll.Pop() as GameObject;
obj.transform.position = pos;
obj.transform.rotation = rot;
obj.gameObject.SetActive( true);
return obj;
}
public void Recyele(GameObject obj) // 回收,让子弹自己回收的话,这里是在子弹上调用的。
{
obj.gameObject.SetActive( false);
sFireBll.Push(obj); // 子弹打出去之后,再回收到栈里。
}
// Update is called once per frame
void Update () {
Control();
if (Input .GetMouseButtonDown(0))
{
GetObj(MFirePos.position, this.transform.rotation );
}
}
public void Control()
{
if (Input .GetKey(KeyCode.W))
{
this.transform.Translate(Vector3 .forward * 0.2f);
}
if (Input .GetKey(KeyCode.S))
{
this.transform.Translate(Vector3 .forward * -0.2f);
}
if (Input .GetKey(KeyCode.A))
{
this.transform.Rotate(Vector3 .up * -1.0f);
}
if (Input .GetKey(KeyCode.D))
{
this.transform.Rotate(Vector3 .up * 1.0f);
}
}
}
三:下面是属于写在子弹身上的代码,子弹发出后,利用对象池,子弹自动回收。具体代码如下;
using UnityEngine;
using System.Collections;
public class spherePao : MonoBehaviour {
void OnEnable () {
Invoke( "Recycle",3.0f);
}
private void Recycle()
{ //调用另一个脚本里的对象池自动回收机制
DuiXiangCi.dd.Recyele(this .gameObject);
}
// Update is called once per frame
void Update () {
transform.Translate( Vector3.forward);
}
}
/* 备注:
- Invoke() 方法是 Unity3D 的一种委托机制
如: Invoke("SendMsg", 5); 它的意思是:5 秒之后调用 SendMsg() 方法;
使1用 Invoke() 方法需要注意 3点:
1 :它应|该在 脚本的生命周期里的(Start、Update、OnGUI、FixedUpdate、LateUpdate)中被调用;
2:Invoke(); 不能接受含有参数的方法;
3:在 Time.ScaleTime = 0; 时, Invoke() 无效,因为它不会被调用到
Invoke() 也2支持重复调用:InvokeRepeating("SendMsg", 2 , 3);
这个方法的意思是指:2 秒后调用 SendMsg() 方法,并且之后每隔 3 秒调用一次 SendMsg () 方法 - /
《完》