【unity小技巧】Unity 存储存档保存——PlayerPrefs、JsonUtility和MySQL数据库的使用

前言

游戏存档不言而喻,是游戏设计中的重要元素,可以提高游戏的可玩性,为玩家提供更多的自由和控制权。看完这篇文章就可以构建属于自己的存储系统了。

PlayerPrefs

它是一个仅仅可以存储字符串、浮点数和整数值数据的类

一、基本介绍

保存

PlayerPrefs.SetString(string KeyName, string Value);
PlayerPrefs.SetFloat(string KeyName, float Value);
PlayerPrefs.SetInt(string KeyName, int Value);
# 最后调用Save函数将这些key存入磁盘
PlayerPrefs.Save()

查找

# HasKeyl函数中可以通过传入Key得到一个bool的返回值
PlayerPrefs.HasKey(string KeyName);

读取

string Value = PlayerPrefs.GetString(string KeyName);
float Value = PlayerPrefs.GetFloat(string KeyName);
int Value = PlayerPrefs.GetInt(string KeyName);

删除

# 删除某个key
PlayerPrefs.DeleteKey(KeyName);

# 删除全部
PlayerPrefs.DeleteAll();

二、Demo

实现按下O键保存玩家的位置数据,并通过按下P键加载玩家的位置数据

using UnityEngine;
public class PlayerDataManager : MonoBehaviour
{
    
    
	public Transform player;
	private void Update(){
    
    
		if (Input.GetKeyDown(KeyCode.O)) Save();//当按下'o'键时保存玩家数据
		if (Input.GetKeyDown(KeyCode.P)) Load();//当按下'P'键时加载玩家数据
	}

	public void Save(){
    
    
		PlayerPrefs.SetFloat("PlayerPositionX", player.position.x);
		PlayerPrefs.SetFloat("PlayerPositionY", player.position.y);
		PlayerPrefs.SetFloat("PlayerPositionz", player.position.z);
		PlayerPrefs.Save();//保存玩家偏好设置
		Debug.Log("Save ok!");
	}
	public void Load(){
    
    
		if (PlayerPrefs.HasKey("PlayerPositionX")&&
		PlayerPrefs.HasKey("PlayerPositionY")&&
		PlayerPrefs.HasKey("PlayerPositionz"))
		{
    
    
			float x = PlayerPrefs.GetFloat("PlayerPositionX");
			float y = PlayerPrefs.GetFloat("PlayerPositionY");
			float z = PlayerPrefs.GetFloat("PlayerPositionz");
			player.position = new Vector3(x,y,z);
			Debug.Log("Load ok!");
		}
	}
}

效果
在这里插入图片描述

三、优缺点

在这里插入图片描述

JsonUtility

它是Unty引擎中提供的一个用于序列化和反序列化JSON数据的工具类,该类提供了三个方法。

一、基本使用

第一个函数ToJson可以将可序列化的对象转换为JSON字符串
第二个可选参数表示是否花费更多的性能将字符转换为更适合阅读的方式

//通过JS0N表示形式创建对象
string json = JsonUtility.ToJson(object obj, bool prettyPrint);

第二个函数FromJson可以将字符转换为对象
Playerlnfo是一个泛型参数,用于指定要将JSoN字符串转换为的对象类型

//生成对象的公共字段的JS0N表示形式
PlayerInfo playerInfo = JsonUtility.FromJson<PlayerInfo>(string json);

第三个函数则可以传入新的数据覆盖到已有对象中,而不是创建新的对象,在频繁读取数据时可以节省开销


//通过读取对象的JS0N表示形式覆盖其数据
JsonUtility.FromJsonOverwrite(string json, object objectTooverwrite);

二、Demo

Application.persistentDataPath是一个持久化的数据路径
在不同的操作系统上,unity会为我们分配不同的持久化数据路径
这样可以确保应用程序在不同平台上都能正确保存和访问

using UnityEngine;
using System.IO;
public class PlayerDataManager : MonoBehaviour
{
    
    
	public Transform player;
	private string savePath;
	private void Awake()
	{
    
    
		//获取存档文件路径
		savePath = Path.Combine(Application.persistentDataPath, "saveData.json");
	}
	private void Update(){
    
    
		if (Input.GetKeyDown(KeyCode.O)) Save();//当按下'o'键时保存玩家数据
		if (Input.GetKeyDown(KeyCode.P)) Load();//当按下'P'键时加载玩家数据
	}
	public void Save(){
    
    
		PlayerGameData saveData = new PlayerGameData();
		saveData.playerPosition = player.position;
		string jsonData = JsonUtility.ToJson(saveData);
		File.WriteAllText(savePath, jsonData);
		Debug.Log("Save ok!");
	}
	public void Load(){
    
    
		//首先对路径做一个安全性检查
		if(File.Exists(savePath)){
    
    
			string jsonData = File.ReadAllText(savePath);
			//将JSON数据反序列化为游戏数据对象
			PlayerGameData loadedData = JsonUtility.FromJson<PlayerGameData>(jsonData);
			player.position = loadedData.playerPosition;
			Debug.Log("Load ok!");
		}else{
    
    
			Debug.Log("Load ok!");
		}
	}
}

[System.Serializable]
public class PlayerGameData
{
    
    
    public Vector3 playerPosition;
    // 可以添加其他的游戏数据字段
}

效果
在这里插入图片描述
不同平台存储的路径不一样,我们可以打印savePath查看自己的存储路径
比如我的就是
在这里插入图片描述

三、优缺点

在这里插入图片描述

Mysql(扩展)

首先,您需要从官方MySQL网站下载MySQL Connector/NET。下载并安装后,您可以在Unity项目中添加对MySQL.Data.dll的引用。

如果您需要在整个应用程序中共享数据库连接,那么使用单例模式可能是一个好主意。这将确保只有一个MySQLConnector实例存在,并且可以在应用程序的任何部分使用它。

要实现这一点,您可以将MySQLConnector类的构造函数设置为私有,并添加一个静态GetInstance方法,该方法返回MySQLConnector类的单例实例。在GetInstance方法中,您可以检查是否已经创建了一个MySQLConnector实例,如果没有,则创建一个新实例并返回它。否则,返回现有实例。

using System.Data;
using MySql.Data.MySqlClient;

public class MySQLConnector
{
    
    
    private static MySQLConnector instance;
    private MySqlConnection connection;
    private string server;
    private string database;
    private string uid;
    private string password;

    private MySQLConnector(string server, string database, string uid, string password)
    {
    
    
        this.server = server;
        this.database = database;
        this.uid = uid;
        this.password = password;
        string connectionString = "SERVER=" + server + ";" + "DATABASE=" + 
            database + ";" + "UID=" + uid + ";" + "PASSWORD=" + password + ";";
        connection = new MySqlConnection(connectionString);
    }

    public static MySQLConnector GetInstance(string server, string database, string uid, string password)
    {
    
    
        if (instance == null)
        {
    
    
            instance = new MySQLConnector(server, database, uid, password);
        }
        return instance;
    }

    public void OpenConnection()
    {
    
    
        connection.Open();
    }

    public void CloseConnection()
    {
    
    
        connection.Close();
    }

    public DataTable ExecuteQuery(string query)
    {
    
    
        MySqlCommand cmd = new MySqlCommand(query, connection);
        MySqlDataAdapter adapter = new MySqlDataAdapter(cmd);
        DataTable dataTable = new DataTable();
        adapter.Fill(dataTable);
        return dataTable;
    }
}

现在,您可以在应用程序的任何部分使用MySQLConnector.GetInstance方法来获取MySQLConnector类的单例实例,并调用其方法来执行查询。例如:

MySQLConnector connector = MySQLConnector.GetInstance("localhost", "mydatabase", "username", "password");
connector.OpenConnection();
string query = "SELECT * FROM mytable";
DataTable dataTable = connector.ExecuteQuery(query);

foreach (DataRow row in dataTable.Rows)
{
    
    
    Debug.Log(row["column1"] + " " + row["column2"]);
}

connector.CloseConnection();

这段代码获取MySQLConnector类的单例实例,并使用适当的服务器、数据库、uid和密码值打开了数据库连接,在名为“mytable”的表上执行了一个SELECT查询,并为查询返回的每一行的“column1”和“column2”值打印到控制台。最后,它关闭了数据库连接。

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。点赞越多,更新越快哦!当然,如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,出于兴趣爱好,于是最近才开始自习unity。如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我可能也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_36303853/article/details/132996925