对象池实例化和删除

问题描述 投票:0回答:0

我为每个实例化的预制件创建了一个对象池。我有2个问题

  1. 如何优化从对象池中删除预制件并将删除的预制件重新添加到池中?该游戏具有三种类型的平台:普通平台、双跳平台和破碎平台。当玩家跳上平台时,破损的平台会倒塌。但是,我的代码没有足够快地从我的池中删除预制件,导致预制件数量不断增加。虽然它删除了平台,但速度很慢,如果玩家长时间玩游戏可能会出现问题。此外,该代码并没有删除所有平台,而是随机留下一些平台。平台应该按照玩家跳上它们的顺序移除,但它们被缓慢删除并且其中一些留在后面。我应该做什么改变?

这是我的 ObjectPool 代码的完整脚本:

public class ObjectPool : MonoBehaviour
{
    public Transform player;

    [Header("General Values")]
  
    public float currentBlockY;
    public float currentBlockX;
    public float disBeforeSpawnBlock = 10f;
    public float minDisBetweenBlocks;
    public float maxDisBetweenBlocks;
    public float minInsOffsetX;
    public float maxInsOffsetX;
    public float brokenMinOffsetX;
    public float brokenMaxOffsetX;
    public int initBlockLines = 10;
    public List<GameObject> normalBlockPool;
    public AnimController animeC1;

    [Header("Grass")]
    public GameObject grassPlatformPrefab;
    public List<Sprite> grassSpriteList;
    int grassSpriteCount;

    [Header("Slime")]
    public GameObject slimePlatformPrefab;

    [Header("Broken")]
    public GameObject brokenPlatform;
    public bool isBrokenPlatform = true;

    private void Awake()
    {
        InitSpawnBlock();
    }

    private void Update()
    {
        if(currentBlockY - player.transform.position.y < disBeforeSpawnBlock)
        {
            ContinueToSpawn();
        }
    }

    private void InitSpawnBlock()
    {
        for (int i = 0; i < initBlockLines; i++)
        {
            GrassSpawner();
        }
    }

    private void ContinueToSpawn()
    {
        normalBlockPool[0].transform.position = new Vector2(Random.Range(minInsOffsetX, maxInsOffsetX), currentBlockY);
        currentBlockY += Random.Range(minDisBetweenBlocks, maxDisBetweenBlocks);

        if(player.transform.position.y > 20 && Random.Range(0f, 2f) < 0.5f)
        {
            isBrokenPlatform = true;
            BrokenPlatformSpawner();

            if(isBrokenPlatform)
            {
                Vector2 blockPos = new Vector2(currentBlockX + Random.Range(brokenMinOffsetX, brokenMaxOffsetX), currentBlockY - Random.Range(1, 5));
                GameObject gO = Instantiate(grassPlatformPrefab, blockPos, Quaternion.identity);
                gO.GetComponent<SpriteRenderer>().sprite = grassSpriteList[grassSpriteCount];
                gO.transform.SetParent(transform);
            }
        }
        else if(player.transform.position.y > 150 && Random.Range(0f, 1f) < 0.1f)
        {
            SlimeSpawner();   
        }
        else 
        {
            GrassSpawner();
        }
        GameObject temp = normalBlockPool[0];
        normalBlockPool.RemoveAt(0);
        normalBlockPool.Add(temp);
        temp.SetActive(true);
    }

    private void GrassSpawner()
    {
        grassSpriteCount = Random.Range(0, grassSpriteList.Count);
        Vector2 blockPos = new Vector2(Random.Range(minInsOffsetX, maxInsOffsetX), currentBlockY);
        currentBlockY += Random.Range(minDisBetweenBlocks, maxDisBetweenBlocks);

        GameObject gO = Instantiate(grassPlatformPrefab, blockPos, Quaternion.identity);
        gO.GetComponent<SpriteRenderer>().sprite = grassSpriteList[grassSpriteCount];
        gO.transform.SetParent(transform);
        normalBlockPool.Add(gO);
    }

    private void SlimeSpawner()
    {
        Vector2 blockPos = new Vector2(Random.Range(minInsOffsetX, maxInsOffsetX), currentBlockY);
        currentBlockY += Random.Range(minDisBetweenBlocks, maxDisBetweenBlocks);

        GameObject gO = Instantiate(slimePlatformPrefab, blockPos, Quaternion.identity);
        animeC1.SlimeAnimationOne();
        gO.transform.SetParent(transform);
        normalBlockPool.Add(gO);
    }

    private void BrokenPlatformSpawner()
    {
        Vector2 blockPos = new Vector2(Random.Range(minInsOffsetX, maxInsOffsetX), currentBlockY);
        currentBlockY += Random.Range(minDisBetweenBlocks, maxDisBetweenBlocks);

        GameObject gO = Instantiate(brokenPlatform, blockPos, Quaternion.identity);
        gO.transform.SetParent(transform);
        normalBlockPool.Add(gO);
        gO.SetActive(true);
    }
}
  1. 我正在尝试创建一个单向平台,当玩家仅从其上方触摸时,该平台必须中断。但我不能那样做,在我触摸那个平台后,它立即消失了。我希望在我只从上面触摸它后立即销毁或移除那个“破损的平台”。可能在某些情况下,我必须从下面触摸那个易碎的平台,它也被摧毁或移除。我使用了 OnCollision 方法,但这不起作用,因为当我从下面发生碰撞时它也会应用代码。有没有办法做到这一点,所以当我从下面碰撞而只从上面碰撞时不会破坏。这是我的代码:
private void OnCollisionEnter2D(Collision2D other)
    {
        if(other.gameObject.tag == "BrokenPlatform")
        {
            other.gameObject.GetComponent<CapsuleCollider2D>().gameObject.SetActive(false);
        }
    }

⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

c# unity3d
© www.soinside.com 2019 - 2024. All rights reserved.