for循环内存过载

Memory overload on for loop

我正在制作一个对象生成脚本,在该脚本的开头调用生成函数,其中有一个 for 循环,每次迭代都会创建一个对象。它首先为它选择一个随机的 X 位置,然后检查它是否在另一个预制件坐标的范围内,这样它们就不会生成得太近或更糟,彼此之间。如果它与另一个预制件在同一坐标中,它将 return 0 并且 Z 轴也是如此。它还会选择一个随机的 Y 轴旋转,因此它不会全部面向同一方向。在此之后它生成预制件并设置它的坐标和旋转,之后它检查 X 或 Z 轴中的坐标是否为 0,如果这两个坐标中的任何一个为 0 它返回一次迭代并销毁最后一个要生成的对象所以它不会泛滥。这非常有效,但是当你想将它设置为生成太多对象时,它会淹没 RAM,因为没有地方可以生成更多对象。我尝试找到最高的 X 位置和最高的 Z 位置并将它们相乘,并将它们都设置为正数,然后将它们除以预制件之间的 space 但这不起作用,因为它将它设置为真的高数。你会如何解决这个问题? 脚本:

using UnityEngine;
using System.Collections;

public class PrefabSpawner : MonoBehaviour {

    public int amountOfPrefabs;
    public int maxAmountOfPrefabs;

    private int currentSpawnedPrefab;

    public float spaceBetweenPrefabs;

    private float positionX;
    private float positionZ;
    private float maxPositionX;
    private float maxPositionZ;
    private float multipliedPosXZ;

    private bool previousSpawnHadZero;

    public GameObject prefab;

    private GameObject point1;
    private GameObject point2;
    private GameObject currentSpawn;

    private Vector2[] positions;

    void Start () {

        currentSpawnedPrefab = 0;
        previousSpawnHadZero = false;

        point1 = gameObject.transform.GetChild (0).gameObject;
        point2 = gameObject.transform.GetChild (1).gameObject;

        if (point1.transform.position.x > point2.transform.position.x)
            maxPositionX = point1.transform.position.x;
        else
            maxPositionX = point2.transform.position.x;
        if (point1.transform.position.z > point2.transform.position.z)
            maxPositionZ = point1.transform.position.z;
        else
            maxPositionZ = point2.transform.position.z;

        multipliedPosXZ = maxPositionX * maxPositionZ;
        if (multipliedPosXZ < 0)
            multipliedPosXZ += multipliedPosXZ + multipliedPosXZ;
        maxAmountOfPrefabs = Mathf.FloorToInt (multipliedPosXZ / spaceBetweenPrefabs);

        if (amountOfPrefabs > maxAmountOfPrefabs)
            amountOfPrefabs = maxAmountOfPrefabs;

        point1.GetComponent<MeshRenderer> ().enabled = false;
        point2.GetComponent<MeshRenderer> ().enabled = false;
        gameObject.GetComponent<MeshRenderer> ().enabled = false;

        positions = new Vector2[amountOfPrefabs];
        SpawnPrefabs (amountOfPrefabs);
    }

    void SpawnPrefabs (int amount) {

        for (int i = 0; i < amount; i++) {

            if(previousSpawnHadZero)
                i -= 1;

            currentSpawn = (GameObject)Instantiate (prefab);

            positionX = GetRandomPositionX ();
            positionZ = GetRandomPositionZ ();

            currentSpawn.transform.position = new Vector3 (positionX, this.transform.position.y + currentSpawn.transform.localScale.y, positionZ);

            currentSpawnedPrefab += 1;

            if (positionX == 0 || positionZ == 0) {
                previousSpawnHadZero = true;
                currentSpawnedPrefab -= 1;
                Destroy (currentSpawn);
            }
            if (positionX != 0 && positionZ != 0) {
                previousSpawnHadZero = false;
                positionX = 0;
                positionZ = 0;
            }
        }
    }

    IEnumerator Pause () {

        yield return null;
    }

    float GetRandomPositionX () {

        //Finds a random position for the X axis and then checks it and returns either 0 if the position is taken or the position if not
    }

    float GetRandomPositionZ () {

        //Finds a random position for the Z axis and then checks it and returns either 0 if the position is taken or the position if not
    }

    bool CheckPositionAvailable (float pos, int axis) {

        //Checks if the position is available.
    }
}

调试代码确实很长,但问题很明显,并且来自 SpawnPrefabs 函数。当前,当您实例化预制件时,您会检查生成的位置是否为 0。如果 0,则在 for 循环中从 i 中减去 1 然后销毁实例化对象,然后从当前循环 1 再次开始 for 循环。

因此 InstantiateDestroy 的组合并在 for 循环中再次重复它会导致内存问题。

要做什么:

您必须重新编写整个函数,这也需要修改您的整个代码。除非需要,否则不要在该循环中实例化和销毁对象。

1。在Start()函数中,创建一个 prefab。

2。通过禁用其 mesh/sprite 渲染器使其在场景中不可见。

3。在for循环中使用该预制件来检查生成的位置是否有效。如果有效,您现在可以 create/instantiate 循环中的对象。

这可以防止在 if (positionX != 0 && positionZ != 0) 时仅创建对象时在循环中实例化和销毁对象。