防止在同一位置连续生成预制件

Prevent Spawning Prefabs At The Same Position In A Row

我正在尝试开发一个统一游戏,它使用数组中随机位置生成的预制件。我遇到的问题是预制件在彼此顶部产生太多次。我试图在其他主题的帮助下防止这种情况发生,不仅在这里,而且 google,但我无法将某些方法应用于我的代码。所以我的目标是继续跟踪最后生成的对象位置,并在与我在障碍脚本中创建的数组不同的位置生成下一个对象。有没有人可以帮助我?

这是我附加到预制件上的障碍脚本。

public class obstacle : MonoBehaviour

{
    private Rigidbody targetRb;
    // Start is called before the first frame update
    private float minSpeed = 12;
    private float maxSpeed = 16;
    private float ySpawnPos = 6;
    private float NewPosition = -1.87f;
    private List<Vector3> spawnPositions = new List<Vector3>();
    private int index;
    public int offset = 1;
    


    void Start()
    {
      
        index = Random.Range(0, spawns.Length);
       
        transform.position = spawns[index];
        
        
       

    }

   

    private void OnTriggerEnter(Collider other)
    {
        Destroy(gameObject);
    }
    Vector3 RandomForce()
    {
        return Vector3.down * Random.Range(minSpeed, maxSpeed);
    }

     Vector3[] spawns = new[]
    //spawns = new Vector3[]
    { 
        new Vector3(-2.16f,7,0), 
        new Vector3(-0.67f,7,0), 
        new Vector3(0.75f,7,0), 
        new Vector3(2.22f,7,0) 
    };
}

这是生成预制件的游戏管理器脚本。

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class GameManager : MonoBehaviour

//spawnera alternatif daha güzel
{
    public List<GameObject> targets;
   
    // Start is called before the first frame update
    public int score;
    public TextMeshProUGUI scoreText;
    public TextMeshProUGUI gameOverText;
    public Button restartButton;
    public bool isGameActive;
    public float spawnRate = 3.0f;
    public Text highScore;
    public Text highestScore;
    
    

   

    void Start()
    {
        isGameActive = true;
        score = 0;
        UpdateScore(0);
        StartCoroutine(SpawnTarget());
        highScore.text = PlayerPrefs.GetInt("HighScore", 0).ToString();
       
        

    }
    IEnumerator  SpawnTarget()
    {
        while (isGameActive)
        {
            yield return new WaitForSeconds(spawnRate);
            int index = Random.Range(0, targets.Count);
            Instantiate(targets[index]);


            UpdateScore(5); 

            if(score > PlayerPrefs.GetInt("HighScore",0))
            {
                PlayerPrefs.SetInt("HighScore", score);
                highScore.text = score.ToString();
            }
            
           
        }
    }
    // Update is called once per frame
    public void UpdateScore(int scoreToAdd)
    {

        score += scoreToAdd;
        scoreText.text = "Score: " + score;

    }

    public void GameOver()
    {
        restartButton.gameObject.SetActive(true);
        gameOverText.gameObject.SetActive(true);
        isGameActive = false;
        Time.timeScale = 0;
        highScore.gameObject.SetActive(true);
        highestScore.gameObject.SetActive(true);


    }
    public void RestartGame()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().name);
        Time.timeScale = 1;
        
        
    }
     
  }
  

堆栈或队列可能有点矫枉过正,因此,我将只保留一个迭代器并检查我们是否超出了数组的范围。我还将把初始位置移动到 GameManager,以便它可以管理生成列表位置中剩余的位置。

    // move the array of locations to the GameManager
    Vector3[] spawns = new[]
    { 
        new Vector3(-2.16f,7,0), 
        new Vector3(-0.67f,7,0), 
        new Vector3(0.75f,7,0), 
        new Vector3(2.22f,7,0) 
    };
    
    private int currentSpawnItr = 0;
    private int maxSpawnItr = 0;

    private System.Random rndm;

    private void Start()
    {
         rndm = new System.Random();
         maxSpawnItr = spawns.Length;
         ShufflePositions();
    }

    IEnumerator  SpawnTarget()
    {
        while (isGameActive)
        {
            yield return new WaitForSeconds(spawnRate);
            int index = Random.Range(0, targets.Count);
            GameObject tmpObstacle = Instantiate(targets[index]);

            tmpObstacle.transform.position = GetNextPosition();

            UpdateScore(5); 

            if(score > PlayerPrefs.GetInt("HighScore",0))
            {
                PlayerPrefs.SetInt("HighScore", score);
                highScore.text = score.ToString();
            }
        }
    }

    private Vector3 GetNextPosition()
    {
         // when we reach the bounds of our spawn array length, shuffle it again
         // and reset our iterator
         if(currentSpawnItr == maxSpawnItr)
         {
             currentSpawnItr = 0;
             ShufflePositions();
         }

         ++currentSpawnItr;
         return spawns[currentSpawnItr-1];
    }

    private void ShufflePositions()
    {
         Vector3 prevLast = spawns[maxSpawnItr-1];
         spawns = spawns.OrderBy(spawn => rndm.Next()).ToArray();
         
         // when our new first spawn was our old last spawn
         if(spawns[0] == prevLast)
         {
              // randomly pick an index to swap our first element to
              int randomIdx = rndm.Next(1, maxSpawnItr);
              spawns[0] = spawns[randomIdx];
              spawns[randomIdx] = prevLast;
         }
    }

我没有测试上面的代码片段。这是您可以采取的更多方向。如果您在执行此操作时遇到问题,请告诉我。