Как я могу переключаться между сценами, не разрушая (освобождая) сцену, которую я покидаю? - PullRequest
2 голосов
/ 03 февраля 2020

Привет, в моей игре есть битвы. В настоящее время битва представляет собой отдельную сцену, и когда игрок подходит к NP C, у нас есть небольшой переход и затем мы покидаем сцену, и мы go на сцену битвы. Как только сцена битвы будет завершена, я хочу вернуться к предыдущей сцене, в которой мы были, и все было точно так же. В настоящее время у меня есть синглтон переключения сцены, называемый scene_switcher с текущей настройкой

extends Node

var _params = null

func change_scene(next_scene, params = null):
    _params = params

    # global_data is another singleton I use for storing state and other global data
    global_data.previous_scene = get_tree().get_current_scene()
    get_tree().change_scene(next_scene)

func return_to_previous_scene(params = null):
    _params = params
    get_tree().get_current_scene().free()
    get_tree().get_root().add_child(global_data.previous_scene)
    get_tree().set_current_scene(global_data.previous_scene)

func get_param(name):
    if _params != null and _params.has(name):
        return _params[name]
    return null

, когда мы вступаем в битву, я использую

scene_switcher.change_scene("res://battlescene.tcsn", {players_deck, opponents_deck})

, которая сохраняет текущую сцену в том виде, в каком она есть и передает данные игрока на сцену битвы.

как только битва заканчивается, я называю return_to_previous_scene(), которую я называю, когда выполняется одно из условий победы, например

scene_switcher.return_to_previous_scene()

, однако я получить сообщение об ошибке:

Attempted to free a locked object (calling or emitting).

Я пытался отложить вызов до простоя, основываясь на этом коде на странице автозагрузки синглтона документа , однако, когда я это сделал:

 call_deferred("scene_switcher.return_to_previous_scene") 

он никогда не вызывается (функция game_over работает, он печатает результат, и мои другие тесты работают с приведенным ниже кодом, я думаю, сцена никогда не простаивает, что означает, что код никогда не получит шанс сработать)

Теперь я могу использовать:

scene_switcher.change_scene("res://map.tcsn", {})

, но это возвращает сцену обратно в исходное состояние и не очень масштабируемо (как я узнаю, какую сцену загружать, если я могу сражаться с людьми в 12 разных уровней?)

Так как я могу остановить текущую сцену. уйти, а потом вернуться к предыдущей сцене со всем, как я ее покинул? Спасибо:)

1 Ответ

1 голос
/ 03 февраля 2020

Я задал этот тот же вопрос на reddit и получил ответ, который решил мою проблему. Копирование здесь для тех, кто может найти этот вопрос в будущем. Все кредиты / u / thomast c

Их ответ :

call_deferred takes a method name only, so:

scene_switcher.call_deferred("return_to_previous_scene")

Alternatively, just use queue_free instead of free, to defer only the freeing.

Я неправильно использовал call_deferred.

Я также сделал небольшую модификацию использования duplicate() на сцене в change_scene, чтобы сохранить копию, которая не была освобождена.

, поэтому

global_data.previous_scene = get_tree().get_current_scene()

стал

global_data.previous_scene = get_tree().get_current_scene().duplicate()

, который теперь работает как ожидалось:)

...