O que você está procurando?
Games

Dados persistentes: Como salvar os estados e configurações do seu jogo

BRONSON ZGEB / UNITY TECHNOLOGIESSenior Content Developer
Feb 23, 2021|10 Min
Dados persistentes: Como salvar os estados e configurações do seu jogo
Esta página da Web foi automaticamente traduzida para sua conveniência. Não podemos garantir a precisão ou a confiabilidade do conteúdo traduzido. Se tiver dúvidas sobre a precisão do conteúdo traduzido, consulte a versão oficial em inglês da página da Web.

Salvar dados é essencial para qualquer jogo. Se você precisa salvar pontuações altas, preferências ou um estado de jogo, o Unity oferece uma variedade de métodos – desde PlayerPrefs até serializar dados, criptografá-los e gravá-los em um arquivo.

Atualizado em 23 de junho de 2021: Como parte do Unite Now 2020, criei uma sessão com dicas sobre persistência de dados no Unity. Ele aborda algumas das maneiras comuns de salvar e carregar dados no seu projeto Unity , mas não é de forma alguma uma lista exaustiva. Ou seja, há mais maneiras de serializar dados do que você jamais precisará, e cada abordagem resolve um problema específico e vem com seu próprio conjunto de pontos fortes e fracos. Esta postagem do blog abordará os mesmos métodos comuns que discuti na sessão Unite Now.

PlayerPrefs

PlayerPrefs não são feitas para salvar estados do jogo. No entanto, elas são úteis, então vamos discuti-las. Você pode usar PlayerPrefs para armazenar as preferências de um jogador entre as sessões, como configurações de qualidade, volume de áudio ou outros dados não essenciais. As PlayerPrefs são armazenadas em algum lugar no seu dispositivo, separadas do seu projeto. O local exato varia dependendo do seu sistema operacional, mas geralmente é um lugar globalmente acessível e gerenciado pelo seu sistema operacional. Os dados armazenados estão em pares chave-valor simples. Devido à facilidade de acesso, eles não estão seguros para usuários que desejam abri-los e modificá-los, e podem ser excluídos acidentalmente, pois são salvos fora do projeto e gerenciados pelo seu sistema operacional.

PlayerPrefs são relativamente fáceis de implementar e exigem apenas algumas linhas de código, mas suportam apenas valores do tipo Float, Int e String, o que torna desafiador serializar objetos grandes e complexos. Um usuário determinado pode superar essa limitação convertendo seus dados salvos em algum formato representado por um desses tipos básicos, mas eu não recomendo isso, pois existem ferramentas melhores para armazenar seus dados.

public void SavePrefs()
{
    PlayerPrefs.SetInt("Volume", 50);
    PlayerPrefs.Save();
}
 
public void LoadPrefs()
{
    int volume = PlayerPrefs.GetInt("Volume", 0); 
}

Por fim, como cada aplicativo Unity armazena todos os seus PlayerPrefs em um único arquivo, ele não é adequado para lidar com vários arquivos salvos ou salvamentos na nuvem, pois ambos exigem que você armazene e receba dados salvos de um local diferente.

JSON

JSON é um formato de dados legível por humanos. Ou seja, é facilmente compreendido por pessoas e máquinas – o que tem vantagens e desvantagens. É muito mais fácil depurar seus dados salvos ou criar novos dados salvos para fins de teste quando você pode lê-los e entendê-los, mas, por outro lado, é fácil para os jogadores lerem e modificarem os dados também. A capacidade de ler e alterar dados é útil se você suporta modding, mas prejudicial se você quer evitar trapaças. Além dessas preocupações, como JSON é um formato baseado em texto, é mais caro para as máquinas analisarem. Ou seja, é mais lento para ler e usa mais memória do que alternativas binárias. Então, se você tiver muitos dados, talvez seja interessante considerar opções que não sejam baseadas em texto. Cada caso de uso é diferente, e são esses tipos de compensações que levam os desenvolvedores a criar muitos outros formatos de dados.

JSON é padronizado e amplamente utilizado em muitas aplicações diferentes. Como resultado, todas as plataformas oferecem forte suporte a ele, o que é útil ao criar jogos multiplataforma. O JSON foi desenvolvido como um protocolo de comunicação para navegadores da web, o que o torna inerentemente bom para enviar dados pela rede. Por isso, o JSON é excelente para enviar e receber dados de um backend de servidor.

JsonUtility

JsonUtility é a API integrada do Unity para serializar e desserializar dados JSON. Semelhante ao PlayerPrefs, também é relativamente fácil de implementar. No entanto, diferentemente de PlayerPrefs, você deve salvar os dados JSON, seja em um arquivo ou em uma rede. Gerenciar o armazenamento de dados por conta própria facilita o gerenciamento de vários arquivos salvos, pois você pode armazenar cada arquivo em um local diferente. Para facilitar isso, escrevi um gerenciador de arquivos básico, que está disponível neste repositório de exemplo.

É importante mencionar que JsonUtility não é uma implementação JSON completa. Se você está acostumado a trabalhar com dados JSON, pode notar a falta de suporte para recursos específicos. Se você estiver interessado em comparar o desempenho de diferentes soluções JSON, experimente este projeto de benchmarking. Tenha em mente que é melhor testar no seu dispositivo de destino, se possível.

As mesmas limitações restringem o JsonUtility como o serializador interno do Unity – ou seja, se você não puder serializar um campo no Inspetor, não poderá serializá-lo para JSON. Para contornar essas limitações, você pode criar tipos de dados simples e antigos (ou PODS) para armazenar todos os seus dados salvos. Quando chegar a hora de salvar, transfira seus dados dos tipos de tempo de execução para um POD e salve-os em um disco. Se necessário, você também pode criar retornos de chamada de serialização personalizados para oferecer suporte a tipos que o serializador do Unity não oferece suporte por padrão.

No tópico JsonUtility, o EditorJsonUtility é outra ferramenta útil. Enquanto o JsonUtility funciona para qualquer objeto baseado em MonoBehaviour ou ScriptableObject, o EditorJsonUtility funcionará para qualquer tipo de mecanismo Unity . Então você pode criar uma representação JSON de qualquer objeto no Unity Editor – ou ir na outra direção e criar um ativo a partir de um arquivo JSON.

Outras bibliotecas

Além das opções de serialização integradas, há outras bibliotecas externas que você também pode usar. A menos que você precise usar especificamente um formato baseado em texto para facilitar a leitura, é melhor usar um serializador baseado em binário:

Ferramentas Binárias

  • MessagePack é um serializador binário eficiente. É eficiente e relativamente fácil de usar. Assim como o JSON, ele está disponível em quase todas as plataformas, então você pode usá-lo para enviar dados através de redes para se comunicar com servidores de backend. Você pode ler mais sobre isso aqui.
  • ProtoBuf e Protobuf-net são outros serializadores binários semelhantes. Também é rápido e eficiente. O Google o desenvolveu como uma alternativa de alto desempenho aos formatos existentes, como XML. Assim como JSON e MessagePack, ele também é adequado para comunicação em redes.
  • BinaryFormatter é uma biblioteca DotNet para armazenar seus objetos diretamente em formato binário. Entretanto, o BinaryFormatter tem vulnerabilidades de segurança perigosas e deve ser evitado. Repito, não use BinaryFormatter. Saiba mais informações sobre os riscos de segurança aqui.

Ferramentas de texto

  • EasySave é um plug-in popular e bem suportado, disponível na Unity Asset Store. Ele permite que você salve todos os seus dados sem escrever nenhum código, o que é excelente para iniciantes. Ele também tem uma API poderosa e flexível que o torna ideal para usuários avançados. Não é gratuito, mas vale o preço se você estiver procurando por uma solução pronta para uso e com todos os recursos.
  • JSON.Net é uma implementação JSON gratuita e de código aberto para todas as plataformas DotNet. Ao contrário do JsonUtility integrado, ele tem todos os recursos. No entanto, isso tem um custo, pois tem um desempenho significativamente inferior ao do JsonUtility integrado. A versão padrão não oferece suporte a todas as plataformas do Unity, mas há uma versão modificada disponível na Unity Asset Store que adiciona suporte.
  • XML é um formato de dados alternativo. Assim como o JSON, ele é relativamente legível por humanos e tem alguns recursos que podem ser úteis para sua aplicação específica, como namespaces. O DotNet tem suporte integrado para XML.
Segurança de dados

Quando o assunto é segurança, a maioria das pessoas pensa primeiro em criptografia. No entanto, quando se trata de armazenar dados localmente no dispositivo de um jogador, a criptografia é relativamente fácil de superar. Mesmo sem quebrar a criptografia, os usuários podem manipular os dados diretamente na memória com ferramentas disponíveis gratuitamente. Em outras palavras, é seguro assumir que qualquer coisa armazenada localmente não é confiável.

Se você precisa de segurança real, sua melhor opção é manter seus dados em um servidor onde os usuários não possam modificá-los. Para que isso funcione, o aplicativo não deve enviar nenhum dado diretamente para o servidor, pois os usuários ainda poderão manipulá-lo. Em vez disso, o aplicativo só pode enviar comandos ao servidor, deixar que o servidor altere os dados e, então, enviar os resultados de volta ao aplicativo. Portanto, se a segurança de dados é vital para você, é melhor saber o mais rápido possível, pois isso afetará a arquitetura do seu projeto.

Para mais informações sobre serialização, confira a página do manual. Se você gostaria de ver isso em ação, confira a sessão Unite Nowque o acompanha.