Usar o PlayerPrefs para ler e gravar dados

Página atualizada :
Data de criação de página :

Ambiente de verificação

Windows
  • Janelas 11
Unity Editor
  • 2021.3.3f1
Pacote do sistema de entrada
  • 1.3.0

Pré-requisitos para esta dica

As configurações a seguir foram feitas com antecedência como premissa para a descrição desta dica.

Inicialmente

Se você já jogou, a maioria de vocês já experimentou. Você provavelmente pausou um jogo e salvou ou carregou seus dados de jogo para sair.

Ao criar um jogo, você geralmente precisa criar essa função de salvar e carregar, definir opções, etc. Aqui, tentaremos conseguir isso usando a maneira mais PlayerPrefs simples de armazenar e carregar dados.

Posicionamento da interface do usuário

Aqui, tentaremos salvar ou ler o conteúdo de entrada colocando os itens de entrada e botões e clicando no botão. Por enquanto, você só precisa de pelo menos dois botões e um campo de entrada, então sinta-se à vontade para colocá-los.

Preparando-se para o processamento da interface do usuário

Primeiro, vamos implementar o botão salvar. Como criar um evento de botão é introduzido nas dicas a seguir, então vou listar apenas as partes relevantes.

Deixe o nome ButtonEvent do script como .

O script tem a seguinte aparência:

using UnityEngine;
using UnityEngine.UI;

public class ButtonEvent : MonoBehaviour
{
  /// <summary>名前入力フィールド。</summary>
  [SerializeField] InputField InputFieldName;

  /// <summary>HP 入力フィールド。</summary>
  [SerializeField] InputField InputFieldHP;

  /// <summary>攻撃力入力フィールド。</summary>
  [SerializeField] InputField InputFieldAttack;

  /// <summary>お金入力フィールド。</summary>
  [SerializeField] InputField InputFieldMoney;

  /// <summary>
  /// 保存ボタンをクリックしたときの処理。
  /// </summary>
  public void OnClickSave()
  {
  }

  /// <summary>
  /// 読み込みボタンをクリックしたときの処理。
  /// </summary>
  public void OnClickLoad()
  {
  }
}

Como é necessário obter ou definir o valor inserido, prepare-o como um campo. Além disso, inclua o método que será chamado quando você clicar em cada botão.

Anexe seu EventSystem script e defina cada campo de entrada. Pode ser qualquer objeto que você queira anexar.

Defina cada método a ser chamado quando o botão for clicado.

Salve o valor

Agora que o método é chamado quando OnClickSave o botão salvar é clicado, o processo do botão salvar é o seguinte.

/// <summary>
/// 保存ボタンをクリックしたときの処理。
/// </summary>
public void OnClickSave()
{
  // 各値を指定したキーに保存します
  PlayerPrefs.SetString("Name", InputFieldName.text);
  PlayerPrefs.SetString("HP", InputFieldHP.text);
  PlayerPrefs.SetString("Attack", InputFieldAttack.text);
  PlayerPrefs.SetString("Money", InputFieldMoney.text);

  // 設定したデータを確定して保存します
  PlayerPrefs.Save();
}

PlayerPrefs.SetString O método é definido como uma chave e um valor a ser salvo. A chave é especificada ao carregar os dados salvos. SetString Aqui estamos chamando o método porque o valor a ser armazenado é uma cadeia de caracteres. int float Se você quiser SetInt salvar um valor de outro tipo, como e , existem métodos como e SetFloat , então chame-os de acordo com o tipo.

PlayerPrefs.Save Finalmente, chame o método para confirmar o salvamento. Na verdade, ele pode ser salvo mesmo se você não chamar esse método, mas é mais seguro chamá-lo.

No entanto, mesmo que você execute o jogo neste momento, ele só salvará o valor, então você não saberá se ele foi salvo corretamente. Se você verificar o local salvo, poderá ver os dados, mas...

Obtenha um valor economizado

Em seguida, implemente o processo de carregamento dos dados salvos. O processamento do botão é o mesmo que o processo de salvamento, portanto, apenas o código do processo de carregamento é descrito aqui.

/// <summary>
/// 読み込みボタンをクリックしたときの処理。
/// </summary>
public void OnClickLoad()
{
  // 指定したキーから値を読み込みます
  InputFieldName.text = PlayerPrefs.GetString("Name");
  InputFieldHP.text = PlayerPrefs.GetString("HP");
  InputFieldAttack.text = PlayerPrefs.GetString("Attack");
  InputFieldMoney.text = PlayerPrefs.GetString("Money");
}

Use o método para PlayerPrefs.GetString carregar os dados salvos. Você pode obter o valor salvo com essa chave especificando a chave especificada em Salvar como um argumento. O valor é recuperado no valor de retorno do método.

Isso também é salvo como uma cadeia de caracteres da mesma forma que ao salvar, por isso GetString chamamos o método. int float Se você GetIntGetFloat estiver salvando com ou , chame o método.

O valor recuperado é refletido no campo de entrada.

Agora você pode salvar e carregar os dados. Não acho que haja elementos difíceis.

Tente movê-lo

Execute para entrar, salvar e carregar. Os dados salvos são persistentes e devem poder ser carregados mesmo se você sair e executar novamente o jogo. Se você puder confirmar o seguinte padrão, acho que não há problema.

  1. Insira um valor
  2. Clique no botão Salvar
  3. Alterar o valor inserido
  4. Clique no botão de importação para confirmar que ele retorna ao valor salvo.
  5. Sair do jogo
  6. Execute novamente o jogo e clique no botão Carregar para ver se você pode recuperar o valor salvo
  7. Insira um valor diferente, salve-o e verifique se você pode ler o mesmo com o valor atualizado

Salvar e carregar um bloco de dados

No exemplo até agora, apenas alguns parâmetros foram salvos. À medida que você realmente faz um jogo, o número de parâmetros a serem salvos aumentará constantemente, e se você lê-los e escrevê-los um por um, o código será enorme. Portanto, ao criar dados para serem realmente salvos, a teoria é combinar os dados a serem salvos em um e, em seguida, escrevê-los todos de uma vez.

Primeiro, crie uma estrutura de dados de salvamento como uma classe. O objetivo é ser capaz de ler e gravar dados de uma só vez, mas também classificar os dados para facilitar o acesso do código a cada parte dos dados.

A seguir estão exemplos de classes de jogos salvos: Ele pode ser escrito em qualquer lugar que possa ser referenciado a partir de outro código. Esta estrutura de classe é uma amostra, então em um jogo real você precisa criá-la para o seu jogo.

/// <summary>セーブデータクラス。</summary>
public class SaveData
{
  public List<Character> Characters;
  public long Money;
}

/// <summary>1キャラクターの情報。</summary>
[Serializable]
public class Character
{
  public string Name;
  public int HP;
  public int Attack;
}

List Na função padrão Unity usada desta vez, se você definir matrizes ou ter várias classes exclusivas, System.Serializable Se você não adicionar um atributo, ele não será convertido corretamente, então Character eu defino o atributo para a Serializable classe.

Depois de criar a classe, crie os dados a serem salvos. Claro, você pode ter instâncias dessa classe ao longo do jogo. Isso depende de como o jogo é feito.

// 保存するデータ作成
var saveData = new SaveData
{
  Money = 10000,
  Characters = new List<Character>
  {
    new Character { Name= "レイシア", HP = 50, Attack = 40, },
    new Character { Name= "アイリ", HP = 56, Attack = 27, },
    new Character { Name= "ニール", HP = 72, Attack = 36, },
    new Character { Name= "トリー", HP = 61, Attack = 30, },
  },
};

Depois de definir JsonUtility.ToJson os dados na instância da classe, converta-os (serialize-os) em uma cadeia de caracteres JSON com o método. Como o valor do objeto é uma única "cadeia de caracteres" chamada JSON com uma estrutura de dados, todos osPlayerPrefs.SetString dados podem ser gravados com uma única chamada para o método.

// オブジェクトを JSON 文字列に変換します
var saveJson = JsonUtility.ToJson(saveData);

// データを保存します
PlayerPrefs.SetString("SaveData", saveJson);
PlayerPrefs.Save();

No entanto, como todos os dados são coletados em um, não é possível salvar apenas parte deles ou ler apenas parte deles. Portanto, é preferível torná-lo uma unidade que seja fácil de resumir, como combiná-lo como um objeto para salvar dados.

Ao ler os dados salvos, você pode fazer o processamento reverso ao salvar. Os dados a serem lidos são uma única cadeia de caracteres, mas o conteúdo é estruturas de dados formatadas em JSON, portanto JsonUtility.FromJson , eles podem ser convertidos (desserializados) em instâncias de classe por métodos. No entanto, como não FromJson temos informações na cadeia de caracteres para qual classe converter, devemos especificar o tipo ao chamar o método.

// データを読み込みます
var loadJson = PlayerPrefs.GetString("SaveData");

// JSON 文字列からオブジェクトにデシリアライズします
var newData = JsonUtility.FromJson<SaveData>(loadJson);

Se você tentar movê-lo, você pode ver que ele está salvo corretamente e pode ser carregado.

A propósito, estamos usando as classes padrão JsonUtility Unity desta vez, mas elas podem não ser capazes de converter classes com estruturas de dados complexas porque não são muito funcionais. Nesse caso, recomenda-se o uso de outras bibliotecas.

Onde os dados são armazenados?

PlayerPrefs Quando você usa uma classe para armazenar dados, o local onde eles são salvos depende da plataforma em que você está executando. Por favor, consulte a página oficial abaixo para saber onde ele está realmente armazenado.

Em alguns ambientes, como o Windows, eles não são armazenados em um arquivo, mas em configurações do sistema, como o Registro. Como não é um arquivo, ele não é adequado para salvar dados salvos no , por exemplo, se os dados salvos forem muito grandes ou PlayerPrefs se você quiser sincronizar os dados salvos com outro ambiente. Por outro lado, se os dados a serem salvos forem do tamanho do nível de opção, ou se for um jogo autônomo que é concluído apenas no ambiente em que está sendo executado, acho que é PlayerPrefs possível salvar os dados no .

Além disso, o caminho do local salvo pode ser afetado pelas configurações "CompanyName" e "ProductName". Se você quiser publicar seu jogo, você precisa decidir sobre esses valores com bastante antecedência e não alterá-los depois de publicar seu jogo.

Sobre a criptografia de dados

Os dados armazenados não são criptografados automaticamente. Se as habilidades do jogador forem salvas como estão, o usuário reescreverá livremente os valores, o que afetará o jogo.

Você precisa criptografar e, em caso afirmativo, qual nível de força é necessário e como você lida com a chave de criptografia? As coisas a considerar variam de jogo para jogo.

Não vou explicar o método de criptografia aqui, mas se você procurá-lo na Internet, é uma linguagem e ferramenta importante, então acho que existem vários métodos. Por enquanto, se você não entender o significado do conteúdo armazenado, mesmo se você abrir o arquivo, e se você adulterar os dados mal, você não será capaz de usar os dados salvos, acho que haverá algum efeito anti-fraude.