Aprendendo a programar jogos em Unity: armazenando e recuperando recordes com PlayerPrefs

Configuraremos o novo elemento no editor, realizaremos intervenções em script controlador e utilizaremos funções de PlayerPrefs.

em 17/05/2026
Seja bem-vindo(a) ao GameDev: Aprendendo a programar jogos em Unity de hoje! Após acrescentarmos, em nosso encontro anterior, um elemento gráfico ao menu inicial que reagirá ao recorde histórico do jogador no game, é hora de codificarmos seu funcionamento, permitindo a exibição do “placar de corações” assim que o jogo for iniciado.


Caso esta seja a primeira vez que você tem contato com textos de nossa série, sinta-se especialmente convidado a juntar-se a nós nesta caminhada. Por meio da elaboração de projetos práticos de programação, aprenderemos muito sobre o processo de desenvolvimento de jogos utilizando a ferramenta Unity. A partir do primeiro tópico, são abordados desde a configuração da ferramenta em seu computador até conceitos de codificação e de montagem de cenas, de estágios e de objetos pertencentes às fases de um projeto.

No momento, estamos desenvolvendo o puzzle tridimensional Consultório do Dr. Tratanildo, um game ambientado em um excêntrico consultório médico, cujos aspectos de gameplay prestam homenagem a clássicos dos anos 1980 e 1990, como Dr. Mario (Nintendo, 1990) e Pac Man (Namco, 1980). Anteriormente, também elaboramos outros dois jogos 2D, Motorista da Pesada e Forest Ping Pong.


Nossa série é desenvolvida de forma a permitir o desenvolvimento de games mesmo a quem não teve oportunidades prévias para aprender programação de jogos ou de sistemas em geral. Para tal, todas as etapas do desenvolvimento de nossos projetos são acompanhadas de explicações e de observações importantes, para que seja possível replicar os passos abordados em seus projetos pessoais.

Se você gostou da ideia de tirar do papel os jogos que sempre sonhou em tornar realidade, venha conosco e vamos juntos nesta jornada rumo a novos conhecimentos!

Dando vida aos corações

Após o devido posicionamento dos objetos que comporão nosso contador visual de recordes, vamos iniciar a codificação de seu comportamento por meio da edição do conteúdo do script controlador de fases do projeto. Embora o contador não seja exibido durante a fase em si, iremos atrelar os comandos necessários para a correta exibição dos corações às etapas iniciais de execução do game.

Para começarmos a realizar as intervenções, vamos abrir nosso projeto para edição. Abra o Unity Hub e clique duas vezes sobre o item referente ao projeto Consultório do Dr. Tratanildo. Na interface inicial do Unity, na aba Project, abra a pasta Assets e, em seguida, Scenes. Clique duas vezes sobre o ícone da cena ConsultorioScene.

Ainda na aba Project, abra a pasta Assets e, em seguida, Scripts. Clique duas vezes sobre o ícone do script ControllerFase para iniciarmos sua edição.

O primeiro elemento a ser acrescido ao código de ControllerFase será uma variável que fará referência ao “coração oculto”, presente no cenário de forma subordinada ao GameObject RecordesCoracoes. Na área inicial do script, dentro do conjunto de variáveis referentes aos elementos da cena, acrescente a seguinte linha de código:

    public Image coracaoRecordeRef;

Essa referência será necessária para que possamos criar e exibir uma quantidade variável de cópias do coração cenográfico, tomando como base as características configuradas para o primeiro elemento elaborado em cena (o já referido “coração oculto” do cenário).

Em seguida, nos deslocaremos para o final do conteúdo de ControllerFase. Imediatamente antes do último fechamento de chaves do arquivo, introduza o seguinte conjunto de códigos ao script.

    public void VerificacaoInicialRecorde()
    {
        if (PlayerPrefs.HasKey("RecordePontuacao"))
            Geral.RecordeAtual = PlayerPrefs.GetInt("RecordePontuacao");
        else PlayerPrefs.SetInt("RecordePontuacao", 0);

        // Ajuste dos corações do menu inicial
        // Será exibido um coração a cada 150 pontos, até um limite máximo de 12 corações

        int auxiliarQtdCoracoes = Geral.RecordeAtual;
        for (int i = 0; i < 12; i++)
            if (auxiliarQtdCoracoes > 0)
            {
                GameObject newCoracao = Instantiate(coracaoRecordeRef.gameObject);
                newCoracao.transform.SetParent(coracaoRecordeRef.transform.parent);
                newCoracao.transform.localScale = Vector3.one;
                newCoracao.SetActive(true);

                auxiliarQtdCoracoes -= 150;
            }
    }

A nova função VerificacaoInicialRecorde será a responsável pela realização de uma sequência de verificações relativas ao placar máximo alcançado pelo jogador em sessões anteriores, além da correta exibição dos corações na tela inicial do game.

Guardando informações entre sessões

No início do código de VerificacaoInicialRecorde, é possível perceber a presença de comandos que fazem referência a uma variável de nome RecordePontuacao. Essa variável é armazenada internamente pelo Unity nas preferências do jogador, por meio do uso de PlayerPrefs.

PlayerPrefs é uma classe de funções do Unity que facilita o armazenamento de informações entre sessões de jogo. Diferentemente das variáveis que declaramos normalmente nos scripts, valores armazenados por meio dos PlayerPrefs não “somem” depois que o jogo é desligado; o Unity trata de guarda-los em arquivos internos do perfil do jogador em sua máquina, recarregando-os ao se iniciar o game.

Por meio do uso de PlayerPrefs, é possível armazenar valores numéricos ou de texto de forma não volátil. Para guardar dados mais complexos entre sessões, como imagens ou outros tipos de multimídia, o uso de PlayerPrefs não é indicado, existindo outras formas mais eficazes, como o armazenamento em arquivos por meio de funções específicas.

Em nosso caso concreto, a função PlayerPrefs.GetInt traz o valor numérico inteiro armazenado na variável RecordePontuacao para Geral.RecordeAtual. Já PlayerPrefs.SetInt é responsável pelo caminho inverso, criando e armazenando o valor 0 na variável RecordePontuacao, caso ele ainda não exista. Na prática, é uma forma simples e rápida de se guardar a pontuação máxima alcançada pelo jogador mesmo após o jogo ser desligado.

O valor de RecordePontuacao é copiado para a variável global RecordeAtual no início da execução do jogo, sendo seu valor atualizado no armazenamento interno do dispositivo apenas caso RecordeAtual ultrapasse RecordePontuacao, comando esse que codificaremos no script mais adiante.

Em seguida, VerificacaoInicialRecorde criará uma nova instância de objeto, baseado em coracaoRecordeRef, a cada 150 pontos acumulados como recorde do jogo, até um limite de doze corações na tela. Além disso, são realizados ajustes referentes a indicação de qual objeto é seu superior hierárquico (função SetParent), a escala de seu Transform (função LocalScale) e a ativação do objeto em cena (função SetActive).

Para que o novo código funcione adequadamente, insira a seguinte linha de comandos imediatamente antes do fechamento de chaves do método Start.

        VerificacaoInicialRecorde();

Por fim, dentro do bloco de comandos referentes à Coroutine pacienteCurado, insira as seguintes linhas de código logo após o comando para concessão de pontos ao jogador.

        if (Geral.PlacarCorrente > Geral.RecordeAtual)
        {
            Geral.RecordeAtual = Geral.PlacarCorrente;
            if (Geral.RecordeAtual > PlayerPrefs.GetInt("RecordePontuacao"))
                PlayerPrefs.SetInt("RecordePontuacao", Geral.RecordeAtual);
        }

Ao final do tratamento de cada paciente, depois de se conceder pontos ao jogador pela sua performance, o jogo verificará se o placar atual é maior do que o recorde corrente. Caso positivo, se o recorde da sessão atual for maior do que o valor do recorde histórico, o valor deste é atualizado, por meio de uma chamada à função PlayerPrefs.SetInt.

Embora possamos utilizar diretamente o valor de RecordePontuacao nas rotinas das lógicas de jogo, como trata-se de uma variável do armazenamento do dispositivo, o ideal é sempre trabalharmos com variáveis em memória e, em momentos específicos (como ao atualizar o recorde), ler e/ou guardar informações em disco. Essa necessidade se impõe por questões de performance, pois os processos de leitura e de escrita em memória RAM são múltiplas vezes mais rápidos do que os que envolvem leituras e escritas a partir de um HD ou de um SSD, o que é o caso de dados guardados por meio do PlayerPrefs.

Salve o script, feche o Visual Studio e retorne ao editor do Unity para realizarmos as intervenções finais que ativarão a exibição dos corações no menu inicial do game.

Ajustes finais

Na aba Hierarchy, selecione o GameObject ControladorFase. Via aba Inspector, dentro do conjunto de atributos do componente Controller Fase, altere o valor do atributo Coracao Recorde Ref para que seja apontado o objeto de nome CoracaoRef. Efetivamente, indicamos qual será o elemento base que servirá como “molde” para o surgimento dos corações na tela.

Experimente executar o projeto, indo à aba Game e clicando sobre o ícone do botão Play. Jogue algumas sessões para aumentar seu placar e note que, ao pararmos e recomeçarmos a simulação de execução do jogo, determinada quantidade de corações surgirão na tela, dependendo do recorde de pontuação alcançado.

Como os valores armazenados em PlayerPrefs sobrevivem ao desligamento do jogo, para que suas variáveis sejam excluídas, é necessário, após a interrupção da simulação de execução, ir ao menu Edit e escolher a opção Clear All PlayerPrefs.


Não se esqueça de, após interromper a simulação, salvar a cena (menu File, Save) e o projeto (menu File, Save Project) antes de fechar o Unity.

Próximos passos

Com mais essa funcionalidade implementada no projeto, conseguimos experimentar uma forma simplificada de armazenarmos e recuperarmos informações entre as sessões de jogo, por meio do uso do PlayerPrefs. Além disso, agregamos ao projeto a interessante exibição de elementos relacionados à performance do jogador, o que pode aumentar o engajamento dos jogadores.

No próximo encontro, prosseguiremos implementando as funcionalidades finais de nosso jogo, além de realizarmos ajustes relacionados à experiência do jogador durante a aventura.

Nosso próximo texto já encontra-se disponível, continue conosco nessa jornada de conhecimento e fique ligado sempre aqui no GameBlast!

Revisão: Ives Boitano
Siga o Blast nas Redes Sociais
Rodrigo Garcia Pontes
Entendo videogames como sendo uma expressão de arte e lazer e, também, como uma impactante ferramenta de educação. No momento, doutorando em Sistemas da Informação pela EACH-USP, desenvolvendo jogos e sistemas desde 2020. Se quiser bater um papo comigo, nas redes sociais procure por @RodrigoGPontes.
Este texto não representa a opinião do GameBlast. Somos uma comunidade de gamers aberta às visões e experiências de cada autor. Você pode compartilhar este conteúdo creditando o autor e veículo original (BY-SA 4.0).