Unity3D 对象池思想 在游戏开发中的运用

Posted spiderljx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity3D 对象池思想 在游戏开发中的运用相关的知识,希望对你有一定的参考价值。

分类:U3D

1.在王者荣耀中,每30秒小兵会出现一波,出现之后会被敌方玩家或敌方小兵销毁,一局游戏下来,小兵会被创建多次,同时也会被销毁,在游戏中,这种频繁的创建和销毁游戏对象是很损耗性能的。在游戏开发过程中,我们会频繁的创建对象和销毁对象,为了提高游戏性能,我们就要用到对象池思想了。

2.在射击游戏中,会频繁的销毁和创建子弹,这就可以用对象池思想了。

什么是对象池?

池,想到了水池,水池是水的集合。所以,对象池就是对象的集合,我们可以初步的按照这种想法来理解对象池。使用原理的话就是,我们在创建游戏对象时,我们就从对象池里取出来,并设置为可见(Obj.seAactive(true)),要销毁对象时又把对象放到对象池里再隐藏(Obj.setActive(false)),以备下次需要从对象池中取对象时使用。

接下来就来看实现过程。

先来说说要实现的效果,我们单机屏幕上的任意一点,然后就可以发射一个子弹(球),并利用对象池对子弹进行存储,达到优化性能的目标;

技术图片

首先创建一个脚本,这个脚本不用继承自Mono,并且用单例模式实现。

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

public class GameObjectManage

    private List<GameObject> gameobjectlist;   // 保存对象的集合
    // 不再累述单例模式
    private GameObjectManage()
    
        gameobjectlist=new List<GameObject>();
    

    private static  GameObjectManage instance;

    public static GameObjectManage GetInstance
    
        get
        
            if (instance == null )
            
                instance=new GameObjectManage();
            
            return instance;
        
    
    // 创建子弹的方法
    public GameObject Instance_obj(GameObject obj)
    
        GameObject result;
        if (gameobjectlist.Count > 0)    // 假如集合不为空,就从集合中取出对象
        
            result = gameobjectlist[0];   // 获得集合中的第一个对象
            result.SetActive(true);          // 并将其显示
            gameobjectlist.Remove(result); // 已获得对象,将这个对象从集合中移除
        
        else    // 集合为空,无法从池中取对象,得直接创建
        
            result= MonoBehaviour.Instantiate(obj) ;
        
        return result;
    
    // 销毁子弹的方法(其实是隐藏子弹)
    public void DestroryObj(GameObject obj)
    
        obj.transform.position=new Vector3(0,0,0);    // 将这个子弹的位置归零
        obj.SetActive(false);     // 并设置不可见
        gameobjectlist.Add(obj);  // 加入到对象池中,为了下次创建对象时备用
    

然后再创建一个脚本用来实现创建子弹,把这个脚本挂载再相机上

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

public class contro : MonoBehaviour

    public GameObject obj;
    private Ray _ray;   // 射线
    void Update()
    
        if (Input.GetMouseButtonDown(0))    
        
            _ray = Camera.main.ScreenPointToRay(Input.mousePosition);//发射射线
           GameObject gb= GameObjectManage.GetInstance.Instance_obj(obj);
           obj.transform.position = transform.position;
           gb.GetComponent<Rigidbody>().velocity = _ray.direction *100;
        
        
    

为了可以实现子弹2秒钟后将其隐藏,我们还需要创建一个脚本来挂载在子弹预制体上,对了,预制体上还需要加刚体。

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

public class cube_contro : MonoBehaviour

    private void OnEnable()    // 不可换成Start哦
    
        StartCoroutine(WaitDestrory());
    

    IEnumerator WaitDestrory()    // 协程实现2秒钟后隐藏
    
        yield return new WaitForSeconds(2f);
        GameObjectManage.GetInstance.DestroryObj(gameObject);
    

通过这几个脚本就可以通过对象池来实现子弹发射效果咯,蛮简单的,但很使用。

多多思考,举一反三,将对象池思想用于自己的游戏中吧!

 

以上是关于Unity3D 对象池思想 在游戏开发中的运用的主要内容,如果未能解决你的问题,请参考以下文章

内置3D对象-Unity3D游戏开发培训

用Unity3D开发赛车游戏碰到的几个问题,求高手解答

Unity3d游戏开发浅谈UGUI中的Canvas以及三种画布渲染模式

Unity 3D 游戏开发Unity3D 入门 - 工作区域介绍 与 入门示例

Unity3D游戏开发初探

unity3d开发2d游戏中Assetbundle有啥作用