DontDestroyOnLoad

Программирование на Юнити.

DontDestroyOnLoad

Сообщение Thamadar 20 апр 2018, 21:39

Есть такая возможность, которая позволяет внести число сцен, которые объект должен пережить, а потом исчезнуть? Ну, например, хочу чтобы объект с тегом "Cat" не пропадал именно 9 раз после перехода со сцены на сцену. Уже на 10 раз - destroy.
Thamadar
UNец
 
Сообщения: 21
Зарегистрирован: 08 апр 2018, 15:43

Re: DontDestroyOnLoad

Сообщение 1max1 20 апр 2018, 23:12

if (текущая сцена != предыдущей сцене) count++;
if (count == 10) Destroy(gameObject);

Ну или в коде загрузке сцены увеличивать count, чтобы не парится с old/current значениями.
Аватара пользователя
1max1
Адепт
 
Сообщения: 5505
Зарегистрирован: 28 июн 2017, 10:51

Re: DontDestroyOnLoad

Сообщение Thamadar 21 апр 2018, 16:26

1max1 писал(а):if (текущая сцена != предыдущей сцене) count++;
if (count == 10) Destroy(gameObject);

Ну или в коде загрузке сцены увеличивать count, чтобы не парится с old/current значениями.

Тут проблемка. Если раскрыть карты, то я собираюсь оставлять спрайт крови гл. персонажа, когда он погибает. После нажатия определенной кнопки - рестарт этого уровня. И ещё. Таких сцен много, если что. А ограничение на выживание - меньше нагрузки. Ну так вот. Как мне на каждом спрайте обновлять счетчик "жизней"? Можно, конечно, сделать все это из костылей, а именно: наделать много тэгов, через множество проверок присваивать их, потом просто обновлять, но это очень сильно будет нагружать устройство и не факт, что правильно работать. Есть какие-то иные идеи?
Thamadar
UNец
 
Сообщения: 21
Зарегистрирован: 08 апр 2018, 15:43

Re: DontDestroyOnLoad

Сообщение Anonymyx 21 апр 2018, 16:36

Сделай отдельный скрипт для спрайта, который будет иметь int sceneReloads и метод который будет увеличивать это значение и проверять не больше ли оно 10. Этот метод подпиши на событие SceneManager.sceneLoaded.
UPD. А, т.е. уровней много, можно разные загружать\перезагружать но спрайты должны оставаться, так?
Аватара пользователя
Anonymyx
Адепт
 
Сообщения: 1973
Зарегистрирован: 05 апр 2015, 15:55

Re: DontDestroyOnLoad

Сообщение Thamadar 21 апр 2018, 17:32

Anonymyx писал(а):Сделай отдельный скрипт для спрайта, который будет иметь int sceneReloads и метод который будет увеличивать это значение и проверять не больше ли оно 10. Этот метод подпиши на событие SceneManager.sceneLoaded.
UPD. А, т.е. уровней много, можно разные загружать\перезагружать но спрайты должны оставаться, так?

Они должны пропадать при загрузке любой сцены, кроме определенной ( сам уровень, где погибает герой ). Получается, что нужно прописать переменную public ( название уровня ), дабы прописывать в самих сценах, а не в коде, или можно все-таки через скрипт, если юнити сам может определять сцену.
Стоп. Как мне найти через другой скрипт все объекты, которые существуют ( спрайты ) и раздать всем по sceneReloads++ перед Application.LoadLevel("RestartUroven'");? Вот допустим, что я пихнул в префаб скрипт с переменной int sceneReloads. Первая проблема - как понять, что настал момент начисления? Вторая - можно ли как-то проверять sceneReloads не через Update? (Если это не будет нагружать как-то заметно устройство, то можно и через Update)
Thamadar
UNец
 
Сообщения: 21
Зарегистрирован: 08 апр 2018, 15:43

Re: DontDestroyOnLoad

Сообщение Anonymyx 21 апр 2018, 17:59

Стоп. Как мне найти через другой скрипт все объекты, которые существуют ( спрайты ) и раздать всем по sceneReloads++ перед Application.LoadLevel("RestartUroven'");? Вот допустим, что я пихнул в префаб скрипт с переменной int sceneReloads. Первая проблема - как понять, что настал момент начисления? Вторая - можно ли как-то проверять sceneReloads не через Update? (Если это не будет нагружать как-то заметно устройство, то можно и через Update)

Кажется не поняли мой код.
У класса SceneManager есть событие которое вызывается когда загружается новый уровень. Если подписать какой-то метод на это событие, то этот метод будет вызываться как только новый уровень загружен. И получается, объект находится в DontDestroyOnLoad, перешли на другую сцену, вызывается метод на спрайте, в котором проверяется кол-во пережитых сцен, и если их больше X - удаляем себя. Ничего не надо прописывать, и Update тут нет вообще.
Как-то так.
Но я прочитал ваш ответ и наверное лучше хранить static лист с элементами в которых хранятся номер сцены, и информация о спрайтах на этой сцене, т.е. позиция и кол-во пережитых сцен. И когда меняем сцену, смотреть есть ли в листе что-нибудь для текущей сцены. Так будет лучше правильнее, ИМХО.
Аватара пользователя
Anonymyx
Адепт
 
Сообщения: 1973
Зарегистрирован: 05 апр 2015, 15:55

Re: DontDestroyOnLoad

Сообщение Thamadar 21 апр 2018, 19:25

Ладно, я понял суть кода. Возникает вопрос: "Как это оформить?". Это я про SceneManager.sceneLoaded. Как мне этим воспользоваться? Впихнуть в void или что?
Thamadar
UNец
 
Сообщения: 21
Зарегистрирован: 08 апр 2018, 15:43

Re: DontDestroyOnLoad

Сообщение 1max1 21 апр 2018, 20:19

Синтаксис:
Используется csharp
class Test: MonoBehaviour
{
    int counter = 0;

    void Start()
    {
        SceneManager.sceneLoaded += SceneLoaded;
    }

    void SceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
    {
        ++counter;

        print(counter);
    }
}
 
Аватара пользователя
1max1
Адепт
 
Сообщения: 5505
Зарегистрирован: 28 июн 2017, 10:51

Re: DontDestroyOnLoad

Сообщение Anonymyx 21 апр 2018, 20:36

Ну ладно, если хотите этим путем...
Синтаксис:
Используется csharp
{
    [SerializeField] int maxSceneLoads = 10;

    int sceneReloads;
    int nativeSceneIndex;

    bool isDestroyed;

    void Awake()
        {
        DontDestroyOnLoad(gameObject);
        SceneManager.sceneLoaded += OnSceneLoad;
        sceneIndex = SceneManager.GetActiveScene().buildIndex;
        }

    void OnSceneLoad(Scene scene, LoadSceneMode loadSceneMode)
    {
        if (isDestroyed)
            return;

        if (scene.buildIndex == nativeSceneIndex)
        {
            sceneReloads++;

            if (sceneReloads > maxSceneLoads)
            {
                Destroy(gameObject);
                isDestroyed = true;
            }

            gameObject.SetActive(true);
        }
        else
            gameObject.SetActive(false);
    }
}


Ну как-то так.
Создаете такой скрипт, и вещаете на спрайт. MaxSceneLoads - кол-во 'выдерживаемых' сцен.
Аватара пользователя
Anonymyx
Адепт
 
Сообщения: 1973
Зарегистрирован: 05 апр 2015, 15:55

Re: DontDestroyOnLoad

Сообщение Thamadar 21 апр 2018, 21:21

Anonymyx писал(а):Ну ладно, если хотите этим путем...
Синтаксис:
Используется csharp
{
    [SerializeField] int maxSceneLoads = 10;

    int sceneReloads;
    int nativeSceneIndex;

    bool isDestroyed;

    void Awake()
        {
        DontDestroyOnLoad(gameObject);
        SceneManager.sceneLoaded += OnSceneLoad;
        sceneIndex = SceneManager.GetActiveScene().buildIndex;
        }

    void OnSceneLoad(Scene scene, LoadSceneMode loadSceneMode)
    {
        if (isDestroyed)
            return;

        if (scene.buildIndex == nativeSceneIndex)
        {
            sceneReloads++;

            if (sceneReloads > maxSceneLoads)
            {
                Destroy(gameObject);
                isDestroyed = true;
            }

            gameObject.SetActive(true);
        }
        else
            gameObject.SetActive(false);
    }
}


Ну как-то так.
Создаете такой скрипт, и вещаете на спрайт. MaxSceneLoads - кол-во 'выдерживаемых' сцен.

error CS0103: The name `sceneIndex' does not exist in the current context
Последний раз редактировалось Thamadar 21 апр 2018, 21:24, всего редактировалось 1 раз.
Thamadar
UNец
 
Сообщения: 21
Зарегистрирован: 08 апр 2018, 15:43

Re: DontDestroyOnLoad

Сообщение Thamadar 21 апр 2018, 21:23

Исправилось, когда добавил public int sceneIndex
Thamadar
UNец
 
Сообщения: 21
Зарегистрирован: 08 апр 2018, 15:43

Re: DontDestroyOnLoad

Сообщение Anonymyx 21 апр 2018, 21:25

Ой, это я просто название переменной не везде поменял...
Синтаксис:
Используется csharp
{
    [SerializeField] int maxSceneLoads = 10;

    int sceneReloads;
    int nativeSceneIndex;

    bool isDestroyed;

    void Awake()
        {
        DontDestroyOnLoad(gameObject);
        SceneManager.sceneLoaded += OnSceneLoad;
        nativeSceneIndex= SceneManager.GetActiveScene().buildIndex;
        }

    void OnSceneLoad(Scene scene, LoadSceneMode loadSceneMode)
    {
        if (isDestroyed)
            return;

        if (scene.buildIndex == nativeSceneIndex)
        {
            sceneReloads++;

            if (sceneReloads > maxSceneLoads)
            {
                Destroy(gameObject);
                isDestroyed = true;
           
                return;
            }

            gameObject.SetActive(true);
        }
        else
            gameObject.SetActive(false);
    }
}


Не надо ничего добавлять, просто переименуйте sceneIndex на nativeSceneIndex
Аватара пользователя
Anonymyx
Адепт
 
Сообщения: 1973
Зарегистрирован: 05 апр 2015, 15:55

Re: DontDestroyOnLoad

Сообщение Thamadar 21 апр 2018, 23:43

Все работает. Спасибо. Счастья, здоровья.
Thamadar
UNец
 
Сообщения: 21
Зарегистрирован: 08 апр 2018, 15:43


Вернуться в Скрипты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 16