对象池使用

本文详细介绍了Unity中对象池技术的实现原理与应用方法。通过具体实例,展示了如何使用对象池来提高游戏性能,减少不必要的对象创建与销毁,特别是在处理大量重复对象如子弹和敌人的场景中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对象池:
对象池就存放需要被反复调用资源的一个空间,当一个对象回大量生成的时候如果每次都销毁创建会很费时间,通过对象池把暂时不用的对象放到一个池中 (也就是一个集合),当下次要重新生成这个对象的时候先去池中查找一下是否有可用的对象,如果有的话就直接拿出来使用,不需要再创建,如果池中没 有可用的对象,才需要重新创建,利用空间换时间来达到游戏的高速运行效果,在FPS游戏中要常被大量复制的对象包括子弹,敌人,粒子等
把脚本分别拖入场景中,不需要做任何操作 using System.Collections; using System.Collections.Generic; using UnityEngine; //创建接口,用于传递对象的生成和销毁 public interface IControl{ //生成时调用 void Spawn (); //销毁对象 void UnSpawn (); } /// <summary> /// 对象池类,用于存放相同类型的对象 /// 1.从对象池中拿出一个游戏对象 /// 2.回收某一个游戏对象 /// 3.回收所有的游戏对象 /// 4.检查某个游戏对象是否在对象池里 /// </summary> /// //对象池类 public class SubPool { //对象池里存放的所有需要频繁创建销毁的游戏对象 List <GameObject> pool = new List<GameObject>(); //要创建的游戏对象的预设体 GameObject prefab; //返回预制体的名字,预制体的名字和对象池的名字一致,在管理对象池的时候 //可以通过预制体的名字找到相应的对象池 public string name{ get{ return prefab.name; } } //自定义一个构造函数 public SubPool(GameObject obj){ prefab = obj; } //从对象池里面拿出一个游戏对象 public GameObject SubPoolSpawn(){ GameObject obj = null; //遍历集合,如果有对象就拿来用,没有的话,直接创建,放进池子 foreach (GameObject item in pool) { //如果没有用(场景中没有显示) if (item.activeSelf == false) { //取出 obj = item; break; } } //说明当前游戏对象没有可复用的游戏对象(有两种情况,一个没有,一个全部再用) if (obj == null) { //创建游戏对象,放在池子里 obj = GameObject.Instantiate (prefab) as GameObject; pool.Add (obj); } // 将游戏对象设置为激活状态 obj.SetActive (true); IControl control = obj.GetComponent<IControl> (); if (control != null) { control.Spawn (); } return obj; } //回收某一个游戏对象 public void SubPoolUnSpawn(GameObject obj){ //如果包含该游戏对象 if (pool.Contains(obj)) { obj.SetActive (false); IControl control = obj.GetComponent<IControl> (); if (control != null) { control.UnSpawn (); } } } //回收所有的游戏对象 public void SubPoolUnSpanwAll(){ //遍历所有未激活的游戏对象,进行回收 foreach (GameObject item in pool) { if (item.activeSelf) { SubPoolUnSpawn (item); } } } //检查某个对象是否在对象池里 public bool SubPoolContains(GameObject obj){ return pool.Contains (obj); } }
把脚本分别拖入场景中,不需要做任何操作



using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//管理类
public class PoolControl {

	#region单利
	private static PoolControl instance;
	private PoolControl (){
		
	}
	public static PoolControl Instance{
		get{
			if (instance == null ) {
				instance = new PoolControl ();
			}
			return instance;
		}
	}
	#endregion
	//创建字典,根据预设体的名字,找到对应的对象池
	Dictionary<string, SubPool> PoolDir = 
		new Dictionary<string, SubPool> ();

	//添加对象池的方法
	private void Register(string name){
		//通过名字加载预制体
		GameObject obj = Resources.Load (name) as GameObject;
		//根据预制体创建相应的对象池对象
		SubPool subPool = new SubPool(obj);
		//将obj对象池对象添加到对象池管理类字典里
		PoolDir.Add (name, subPool);
	}
	//根据预制体的名字找到对象池的对象,调用对象池中返回游戏对象的方法
	public GameObject Spawn (string name){
		SubPool subPool;
		//如果字典中不包含对应的key为name的键值对
		if (!PoolDir.ContainsKey(name)) {
			//此时需要在字典中创建对应的对象池
			Register (name);
		}
		subPool = PoolDir [name];
		return subPool.SubPoolSpawn ();
	}

	//回收一个游戏对象的方法
	public void UnSpwan(GameObject obj){
		//找对游戏对象所在的池子

		foreach (SubPool item in PoolDir.Values) {
			if (item.SubPoolContains(obj)) {
				//让该对象池回收它
				item.SubPoolUnSpawn (obj);
				break;
			}
		}
	}


}

创建一个Sphere球,把bittle脚本挂在Sphere身上,并把Sphere重命名为Butttle,
并把Buttle拖成预设体,放在Resources文件中
 
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class bittle : MonoBehaviour,IControl {
	//实现接口里面的方法
	public void Spawn ()
	{
		Debug.Log("表示从对象池中生成");
		//从游戏对象创建开始执行,延迟3秒销毁
		Invoke ("DeleteSelf", 3);

	}
	public void UnSpawn ()
	{
		Debug.Log("表示从对象池中销毁");
	}

	void Start () {
		
	}
	
	void Update () {
		transform.position += Time.deltaTime * Vector3.forward * 20;
	}
	//子弹销毁
	void DeleteSelf(){
		//回收游戏对象
		PoolControl.Instance.UnSpwan (gameObject);     
		//重置一下位置
		transform.position = Vector3.zero;
	}
}


创建一个胶囊体,并把player脚本挂在身上,运行的时候,按下空格的时候发射子弹

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

public class Player : MonoBehaviour {

	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
		if (Input.GetKeyDown(KeyCode.Space)) {
			//创建子弹
			GameObject obj = PoolControl.Instance.Spawn ("Bullet");
			obj.transform.position = transform.position;
		}
	}
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值