Usar o PlayerPrefs para ler e gravar dados
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ê GetInt
GetFloat
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.
- Insira um valor
- Clique no botão Salvar
- Alterar o valor inserido
- Clique no botão de importação para confirmar que ele retorna ao valor salvo.
- Sair do jogo
- Execute novamente o jogo e clique no botão Carregar para ver se você pode recuperar o valor salvo
- 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.
- PlayerPrefs
- 【Unidade】 Localização dos dados armazenados no PlayerPrefs no WebGL no Windows (IndexedDB)
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.