Imagem de Capa

Como Fazer um Player Persistente Entre as Cenas no Godot

Nesse artigo é mostrado uma gambiarra para fazer a persistência do Player entre as cenas.

By João Paulo Siqueira At Thu Dec 30 2021 23:09:54 GMT+0000 (Coordinated Universal Time)

#godot

[Artigo em Desenvolvimento]

Olá, acho que eu posso te ajudar com isso. Eu estou trabalhando em um protótipo que faz basicamente isso que você quer. O que você precisa fazer é manter uma instância única do seu Player em um Script no Autoload e depois instanciar o Objeto Player dentro das suas Cenas usando um Position2D para manter a posição e a sequência do Player dentro da Árvore da Cena. Primeiro você cria um Script, por exemplo LoadPlayer.gd, e registra ele no Autoload. Dentro do Script, você escreve o seguinte código:

LoadPlayer.gd

extends Node

var PlayerInstance = load("res://scenes/Player.tscn") var player = null

func _ready() -> void: player = PlayerInstance.instance() # Main é a minha Cena, ele teve ter um Position2D chamado Spawner mover_player("Main")

func mover_player(cena): # se tem um pai if player.get_parent(): # então remove o Player player.get_parent().remove_child(player) # pega a cena, ela já está carregada na memória var node = get_node("/root/" + cena) # Spawner é um Pointer2D, é onde eu quero que o Player Apareça var spawner = node.get_node("Spawner") player.set_position(spawner.get_position()) # Adiciono o Player na Nova Cena node.add_child(player) # Por fim, mudo a ordem do Player na Árvore da Cena # Para que o Player não fique sobre os outros Nós node.move_child(player, spawner.get_position_in_parent())

Depois disso, para mudar de cena, você precisa do seguinte código:

#Player.gd extends KinematicBody2D

var Tavern = preload("res://scenes/Tavern.tscn").instance()

func get_input(): if Input.is_action_just_pressed("ui_accept"): # Mudo a localização da minha Cena Tavern.position.y = 1024 if not get_tree().get_root().has_node("Tavern"): # Eu mantenho todas as Cenas carregadas, elas só estão em posições diferentes get_tree().get_root().add_child(Tavern) # Pego o Script Global var LoadPlayer = get_node("/root/LoadPlayer") # Mudo o Nó Player para dentro da Cena Tavern LoadPlayer.mover_player("Tavern") # A Cena Tavern também precisa de um Position2D chamado Spawner

func _physics_process(delta: float) -> void: get_input()

E é isso, eu ainda estou trabalhando nesse código, mas a funcionalidade principal está aí. Ainda tem que mudar algumas coisas, por exemplo, eu estou criando a instância da Tavern dentro do Player.gd, o que não é certo, eu coloquei ela aí para simplificar o exemplo, mas eu poderia manter essa instância em um outro Script Global. Eu estou mantando todas as Cenas carregadas na memória, porque eu quero testar uma outra lógica parecida com os NPC's, quero tentar fazer os NPC's mudarem de cenas. Se tiver alguma dúvida, fique a vontade em perguntar ;)