segunda-feira, 12 de janeiro de 2015

Salvar e Carregar em Blueprints

Para Salvar um jogo precisamos definir todas as informações que são necessárias armazenar para que seja possível carregar o jogo posteriormente. Estas informações precisam ser reunidas em forma de variáveis em um Blueprint do tipo "SaveGame". A imagem abaixo mostra as funções usadas para Salvar e Carregar um jogo.


Para ilustrar o uso destas funções vamos adicionar a opção de Quick Save e Quick Load ao jogo que desenvolvemos na 1ª parte deste blog. O jogo está descrito neste artigo: "Um jogo bem simples em Blueprints".

Mas não se preocupe se você não tiver feito o jogo da 1ª parte, pois os conceitos apresentados neste artigo podem ser facilmente adaptados para o seu jogo.

O primeiro passo é criar um novo Blueprint do tipo SaveGame. Para isso pesquise por "Save" na opção "All Classes" e escolha como Classe Pai (Parent Class) a classe "SaveGame" como mostra esta imagem :


Para o meu exemplo, eu escolhi o nome "SaveInfo" para este novo Blueprint que conterá todas as informações que serão salvas.

Vamos salvar as variáveis que definem o estado atual do jogo. As variáveis são Level, Score, StatueCont e Time. Estas variáveis são do tipo Inteiro e estão descritas no artigo: "GameHUD: Inicializando as variáveis com uma Macro".

Além destas variáveis, vamos gravar também as Transformações do jogador e de todas as "Statues" do jogo. Uma variável do tipo Transformação contém informações sobre a Posição, Rotação e Escala de um Ator. Desta forma ao carregar um jogo será possível colocar o jogador e as "Statues" na posição que estavam quando o jogo foi salvo.

As variáveis do Blueprint "SaveInfo" são as seguintes:


Todas as variáveis foram marcadas como "Editable" (representado pelo ícone com o olho aberto) para facilitar o acesso às variáveis em outros Blueprints.

O Blueprint "SaveInfo" é usado apenas para guardar as informações. Não será criado nada no EventGraph dele.

Neste exemplo o Blueprint "GameHud" será responsável pela opção de Quick Save e Quick Load. É necessário adicionar ao "GameHud" uma variável do tipo SaveInfo para preenchermos com as informações que serão salvas. O nome desta variável será "SaveInfoVar".


No Blueprint "GameHud" será criado os eventos relacionados a tecla F9 para o Quick Save e a tecla F10 para o Quick Load. Para que os eventos de Input funcionassem no Blueprint "GameHud", foi necessário usar a função Enable Input como mostra a imagem abaixo:


Para organizar o Blueprint eu criei as Macros SaveGameVars, SaveTransforms, LoadGameVars e LoadTransforms. Elas são usadas para mover as informações entre o Blueprint SaveInfo e os Blueprints do jogo. O conteúdo destas Macros será mostrado posteriormente.

A implementação do Quick Save ficou desta forma:

Clique para aumentar

Vamos analisar cada uma das Funções e Macros usadas:
  • Create Save Game Object: Cria um objeto do tipo indicado no parâmetro "Save Game Class". Em nosso exemplo a classe usada é "SaveInfo".
  • Cast To SaveInfo: Converte para o tipo SaveInfo o objeto que foi criado.
  • Set SaveInfoVar: Armazena o objeto criado na variável SaveInfoVar.
  • Macro SaveGameVars: Copia os valores das variáveis Level, Score, StatueCont e Time do GameHud para o objeto SaveInfoVar.
  • Macro SaveTransforms: Copia os valores das Transformações do Jogador e das Statues para o objeto SaveInfoVar.
  • Save Game to Slot: Salva o objeto SaveInfoVar, usando como SlotName = "BP_Game" e UserIndex = 0.

Quando for executado o Quick Save, o Blueprint irá criar um arquivo usando o nome do Slot e a extensão ".SAV". Neste exemplo foi criado o arquivo BP_Game.SAV na pasta "NomeProjeto->Saved->SaveGames". Este arquivo contém os dados de todas as variáveis que criamos no Blueprint SaveInfo. O parâmetro UserIndex permite que diversos objetos SaveGame sejam salvos em um mesmo arquivo. Para isso basta mudar o valor de UserIndex.


Abaixo está a implementação do Quick Load

Clique para aumentar

As Funções e Macros usadas:
  • Does Save Game Exist: Verifica se existe um jogo salvo com o SlotName e UserIndex informado.
  • Branch: Usado para que as próximas funções só sejam executadas se existir o jogo salvo.
  • Load Game from Slot: Carrega um jogo a partir de um arquivo e cria um objeto contendo as informações que foram salvas.
  • Cast To SaveInfo: Converte para o tipo SaveInfo o objeto que foi criado.
  • Set SaveInfoVar: Armazena o objeto criado na variável SaveInfoVar.
  • Macro LoadGameVars: Copia os valores das variáveis Level, Score, StatueCont e Time do objeto SaveInfoVar para o GameHud.
  • Macro LoadTransforms: Copia os valores das Transformações do objeto SaveInfoVar para o Jogador e para as Statues.

Para concluir o artigo vamos apenas examinar o conteúdo de cada uma das macros criadas.

  • Macro SaveGameVars:

Clique para aumentar

Nesta Macro estamos apenas armazenando nas variáveis do objeto SaveInfoVar os valores das variáveis do GameHud.

  • Macro SaveTransforms:

Clique para aumentar

A Transformação do jogador é obtida usando as Funções GetPlayerCharacter e GetActorTransform. Para salvar as Transformações das "Statues" vamos usar Arrays com o ForEachLoop

Usamos a função "Get All Actor of Class" para obter um Array contendo todas as "Statues" que estão no jogo. Usando o ForEachLoop pegamos a Transformação de cada "Statue" e adicionamos ao Array StatuesTransforms do objeto SaveGameInfo.

  • Macro LoadGameVars:

Clique para aumentar

Esta Macro foi baseada na Macro StartGame. Só que ao invés de usar valores padrões para iniciar as variáveis, estão sendo usados os valores carregados na variável SaveInfoVar.

  • Macro LoadTransforms:

Clique para aumentar

Realiza o processo inverso ao da Macro SaveTransforms, copiando os valores das Transformações do objeto SaveInfoVar para o Jogador e para as Statues.