2017-08-22 9 views
0

Je crée un script spawn d'objet dans lequel au début du script la fonction spawning est appelée et dans laquelle il y a une boucle for qui crée un objet à chaque itération. Il choisit d'abord une position X aléatoire pour lui, puis vérifie s'il se trouve dans une plage d'autres coordonnées préfabriquées afin de ne pas apparaître trop près ou pire, les unes dans les autres. S'il est dans les mêmes coordonnées qu'un autre préfabriqué, il retournera 0 et il en sera de même pour l'axe Z. Il sélectionne également une rotation aléatoire de l'axe Y pour ne pas tous faire face à la même direction. Après cela, il engendre le préfabriqué et définit ses coordonnées et rotation après quoi il vérifie si les coordonnées dans l'axe X ou Z sont 0, et si l'un de ces deux est 0, il retourne une itération et le dernier objet à engendrer est détruit donc ça n'inonde pas. Cela fonctionne parfaitement mais quand vous voulez le configurer pour engendrer trop d'objets il inonde la RAM car il n'y a nulle part où engendrer plus d'objets. J'ai essayé de trouver la position X la plus élevée et la position Z la plus élevée et de les multiplier, et de les placer à la fois positives, puis de les diviser par l'espace entre les préfabriqués, mais ça ne marche pas. Comment voulez-vous résoudre ce problème? Script:Surcharge de mémoire pour la boucle

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. 
    } 
} 
+0

Vous venez de nous donner un mur de code, pouvez-vous nous fournir un [mcve]? – DavidG

+0

Eh bien, la plupart du temps tout fait partie du problème, mais je vais essayer de supprimer certaines choses –

+0

Vous devez vraiment, personne ne veut déboguer tout ce code. – DavidG

Répondre

2
code

est vraiment long pour le débogage, mais le problème est clairement visible et est de la fonction SpawnPrefabs. Actuellement, lorsque vous instanciez un préfabriqué, vous vérifiez si la position générée est 0. Si 0, vous soustrayez 1 du i dans la boucle for puis détruisez l'objet instancié, puis recommencez la boucle for à partir de la boucle-1 actuelle. Par conséquent, la combinaison de Instantiate, Destroy et de la répétition dans la boucle for provoque le problème de mémoire.

Que faire:

Tu dois réécrire toute la fonction et cela nécessitera une modification dans votre code tout aussi. Ne pas instancier et détruire l'objet dans cette boucle sauf si nécessaire.

.Dans la fonction Start(), créer une préfabriquée.

.Faire en sorte qu'il soit invisible dans la scène en désactivant son moteur de rendu mesh/sprite.

. Utilisez ce préfab dans la boucle for pour vérifier si la position générée est valide. Si c'est valide, vous pouvez maintenant créer/instancier un objet dans la boucle.

Cela empêche l'instanciation et la destruction d'objets dans la boucle lorsque vous créez uniquement des objets lorsque if (positionX != 0 && positionZ != 0).