我在 Unity 中的对象池有问题

I have issue with Object Pooling in Unity

提问人:user21596799 提问时间:11/14/2023 最后编辑:Morionuser21596799 更新时间:11/15/2023 访问量:53

问:

我的 Get() 函数在对象池中继续实例化更多对象。我找不到问题,没有错误。 这是 Spawner 类。

public class OPool : MonoBehaviour
{
    public Bullet bulletPrefab;
    public UnityEngine.Pool.ObjectPool<Bullet> _bulletPool;
    public static OPool _OPool;
    public void Start()
    {
        _bulletPool = new UnityEngine.Pool.ObjectPool<Bullet>(createFunc: InstantiatePoolBullet, actionOnGet: GetBulletFromPool,
            actionOnRelease: ReturnBulletToPool,DestroyBullet, true, 15,20);
    }

    public void Update()
    {   
        transform.position = transform.parent.position + new Vector3(0f, 3.5f, 2.5f);
    }

    public Bullet InstantiatePoolBullet()
    {
        Bullet bullet = Instantiate(bulletPrefab, transform);
        bullet.SetPool(_bulletPool);
        return bullet;
    }

    public void GetBulletFromPool(Bullet bullet)
    {
             bullet.transform.position = transform.position;
             bullet.transform.rotation = transform.rotation;             
             bullet.gameObject.SetActive(true);      
    }

    public void ReturnBulletToPool(Bullet bullet)
    {
        bullet.gameObject.SetActive(false);
    }
    public void DestroyBullet(Bullet bullet)
    {
        Destroy(bullet.gameObject);
    }
 
}

这是我的 Bullet 类

public class Bullet : MonoBehaviour
{
    public float speed;
    private ObjectPool<Bullet> _pool;
    public float _deadtime = 0.7f;
    private float _currentTime;
    private Rigidbody rb;
    public int damage;
    public static Bullet bullet;
    private void Awake()
    {
        rb = GetComponent<Rigidbody>();
        _currentTime = _deadtime;
    }

    private void Start()
    {
        bullet = this;
        ApplyVelocity();
    }

    private void Update()
    {
        if (_currentTime > 0)
        {
            _currentTime -= Time.deltaTime;
        }
        else
        {
            DestroyBullet();
        }
    }

    public void SetPool(ObjectPool<Bullet> pool)
    {
        _pool = pool;
    }

    private void OnEnable()
    {
        ApplyVelocity();
        _currentTime = _deadtime;
    }
    
    private void ApplyVelocity()
    {
        rb.velocity = speed * transform.forward;
    }

    private void DestroyBullet()
    {
        if (_pool != null)
        {
            _pool.Release(this);
        }
        else
        {
            Destroy(gameObject);
        }
    }

这就是我调用 Get 函数的地方,它在 Player 脚本中。

    void Update()
    {
        if (transform.IsChildOf(RunPlayer.Instance.transform) && RunPlayer.Instance._state == NumState.Running)
        {
            _State = State.Free;

        }
        if (_State == State.Free)
        {
            canShoot = true;
            charAnim.SetBool(Starting, true);
            StartCoroutine(ShootR());
        }
    }
    public enum State
    {
        Idle,
        Free
    }
    public IEnumerator ShootR()
    {
        while (canShoot)
        {
            if (downShootRate)
            {
                yield return new WaitForSeconds(.150f);
            }
            yield return new WaitForSeconds(.145f);
            bulletPool._bulletPool.Get();
        }
    }

我只是编码新手,谢谢你抽出时间。对我有什么建议吗?我找不到问题所在。

我尝试过调试,寻找解决方案,但它仍然如此。我希望我能找到问题,为什么它一直在实例化。

unity-game-engine 3D 游戏开发 对象池

评论

0赞 BugFinder 11/14/2023
没有使用过 unitys objectpool 并且总是自己制作,它是否可能在重用之前制作最大数量的东西?
0赞 user21596799 11/14/2023
我能看到你自己的对象池吗?或者有没有类似于您所说的教程?
0赞 BugFinder 11/14/2023
我的只是一个列表..使用了布尔值的结构;游戏对象的东西..所以,item=list.first_o=>!o.isused) - 如果 item==null && poolsize < list.cont 然后将新的添加到列表中,否则标记已使用并交还..在交接时,马克习惯于不。

答:

0赞 Ryan Gray 11/15/2023 #1

你真的应该看看文档。您将看到它们没有在任何地方实例化对象,因为对象池的方法已经在需要时创建了一个新对象。仔细看看他们的方法,这就是你所类比的。GameObject.Instantiate(...)Get()CreatePooledItem()InstantiatePoolBullet()

因此,在您的方法中,您有:

public Bullet InstantiatePoolBullet()
    {
        Bullet bullet = Instantiate(bulletPrefab, transform);
        bullet.SetPool(_bulletPool);
        return bullet;
    }

我相信每次对象池这样做时,它实际上都会实例化一个新的项目符号。

当有文档可以向你解释时,没有必要假设这些东西是如何工作的,尽管并不总是最具描述性的。虽然在这种情况下,它已经足够了。

我希望这对您有所帮助。