Как реализовать случайное появление объектов из списка с последующим их удалением в Unity?

Здравствуйте! <br/> Не могли бы вы помочь мне с кодом для Unity? <br/> У меня есть 10 объектов, которые изначально скрыты. Мне нужно реализовать функциональность, при которой нажимая на кнопку, будет становиться видимым случайный объект, а при следующем нажатии этот объект скрывается, и появляется новый случайный объект из оставшихся. <br/> Когда все объекты будут показаны, я хотел бы, чтобы все 10 объектов снова стали доступны и процесс начал повторяться. <br/> Все эти действия должны осуществляться с помощью одной кнопки на одной сцене. <br/> <br/> У меня уже есть некоторый код, но он не обеспечивает желаемый результат, так как приводит к частым повторам из 10 объектов: <br/> <pre><code>public class Breakfast : MonoBehaviour
{
    public GameObject[] obj;

    public void Start()
    {
        Spawn();
    }

    public void Spawn()
    {
        obj[Random.Range(0, obj.Length - 1)].SetActive(true);
    }

    public void Push()
    {
        SceneManager.LoadScene("Breakfast");
    }
}</code></pre>
  • 5 января 2025 г. 10:54
Ответы на вопрос 2
Здравствуйте! Давайте доработаем ваш код, чтобы реализовать функциональность, описанную вами. Мы будем использовать список для отслеживания оставшихся объектов и объекту для случайного их появления и удаления.

Вот пример кода, который может вам помочь:

```csharp
using System.Collections.Generic; // Не забудьте добавить эту директиву
using UnityEngine;

public class Breakfast : MonoBehaviour
{
    public GameObject[] obj; // Массив объектов
    private List<int> remainingIndices; // Список индексов оставшихся объектов
    private GameObject currentObject; // Текущий видимый объект

    void Start()
    {
        // Инициализируем список индексов всех объектов
        remainingIndices = new List<int>();
        for (int i = 0; i < obj.Length; i++)
        {
            remainingIndices.Add(i);
        }

        // Скрываем все объекты изначально
        foreach (GameObject gameObject in obj)
        {
            gameObject.SetActive(false);
        }
    }

    public void Push()
    {
        if (currentObject != null) 
        {
            // Скрываем активный объект
            currentObject.SetActive(false);
        }

        // Проверяем, остались ли индексы для отображения
        if (remainingIndices.Count == 0)
        {
            // Если индексы закончились, восстанавливаем все
            for (int i = 0; i < obj.Length; i++)
            {
                remainingIndices.Add(i);
            }
        }

        // Выбираем случайный индекс из оставшихся
        int randomIndex = Random.Range(0, remainingIndices.Count);
        int objectIndex = remainingIndices[randomIndex];

        // Убираем индекс из списка оставшихся
        remainingIndices.RemoveAt(randomIndex);

        // Активируем новый случайный объект
        currentObject = obj[objectIndex];
        currentObject.SetActive(true);
    }
}
```

### Как это работает:
1. **Список оставшихся индексов (`remainingIndices`)**: Мы используем его для отслеживания объектов, которые еще не были показаны.
2. **В методе `Start()`**: 
   - Инициализируем список `remainingIndices`, заполняя его индексами всех объектов вашего массива.
   - Скроем все объекты.
3. **В методе `Push()`**: 
   - Если есть активный объект, мы сначала его скрываем.
   - Если `remainingIndices` пуст, это значит, что мы уже показали все объекты, и мы восстанавливаем все индексы.
   - Затем выбираем случайный индекс из оставшихся, удаляем его из списка и активируем соответствующий объект.

Теперь вы можете прикрепить данный скрипт к любому объекту в вашей сцене, настроить массив `obj` в инспекторе и привязать метод `Push()` к кнопке для получения желаемого результата.
Должно работать, не проверял. 
using UnityEngine;
using System.Collections.Generic;

public class Breakfast : MonoBehaviour
{
    public GameObject[] objects;
    private List<int> _remainingObjects;
    
    public void Start()
    {
        InitializeObjects();
    }

    public void Push()
    {
        if (_remainingObjects.Count == 0)
        {
            InitializeObjects();
        }

        int randomIndex = Random.Range(0, _remainingObjects.Count);
        int objectToShowIndex = _remainingObjects[randomIndex];

        objects[objectToShowIndex].SetActive(true);

        _remainingObjects.RemoveAt(randomIndex);
    }

    private void InitializeObjects()
    {
        _remainingObjects = new List<int>();
        for (int i = 0; i < objects.Length; i++)
        {
            _remainingObjects.Add(i);
            objects[i].SetActive(false);
        }
    }
}
Похожие вопросы