前言:数据库在游戏中的应用
在(客户端)Unity 需引入
在游戏开发中,有的时候会因为数据库的设计而头疼,作者最近在做一个 类似 VS 编辑器的项目,因为 数据库和 ADO 困惑了很久,快炸了,天天抓狂(头发还有),做着做着今天晚上豁然开朗了,当然后面有一个 主程大佬带飞,很幸运,接下来将会记录数据库的设计方式、还有就是 C# 中连接数据库、查询数据库中的内容、数据库的结构类的写法:
首先我们项目需要实现的功能就是:
这里是有三个类的(Student,Teacher,Teaching)这里我只分析一种,也就是 Student
首先可以看到右上角的问题描述,对应着不同的类,当类图发生改变的时候,文字描述也会开始进行改变,紧接着甲方(老板)需要做的事情就是我们(甲方)根据类图格式来填空(UI 界面比较简单 请忽略谢谢),右边代码框中留出来的 Button 按钮就是需要进行补充的,具体补充的内容就不说了,带过了,每次在代码框中点击了一次之后 在类图下面的 框框中输入 内容,然后根据用户输入的内容 跟数据库中的内容进行对比(稍后会曝光数据库的设计),如果说用户输入的内容和数据库中的内容相同的时候,就开始对比写下一个,反之跟数据库中的内容不相同的时候,将用户输入的值(也就是代码框中填充的代码)变为红色;输入正确以后也就是需要用户输入第二个值,再去跟数据库中的内容进行对比,以此类推,一直比到最后,全部比完以后右下角的结果框中 出现一个运行的结果,当用户点击了 (默认的时候是没有办法进行点击的)提交并运行的时候,保存 中间代码框中的文本,并且生成 Java 格式的代码(我不知道为神马要用 C# 去生成 Java代码,反正甲方给的需求是这样的)并且保存在 Assets文件夹下,最后打包成 WebGL 的包发布到网页上,紧接着拿着这个东西到 Java 搭建的服务器上面去运行…我也是醉了,
最后笔者简单的算了算 Unity 、WebGL 、 MySql 、 服务器 涉及到 4 个端,笔者这个项目亏死,害,不过既然接了,就当学习一下,毕竟 吃一堑长一智。。。。
接下来上数据库的设计以及代码:
紧接着上 在 C# 中连接以及访问数据库的类了:
//==========================
// - FileName: MySqlHelp.cs
// - Created: true.
// - CreateTime: 2020/04/26 15:27:04
// - Email: 1670328571@qq.com
// - Region: China WUHAN
// - Description: 数据库工具类 、 MysqlHelp 封装在 GameManager 中,由于作者比较喜欢用大单例
//==========================
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
public class MySqlHelp
{
private MySqlConnection mySqlConnection;
private string _host;
private string _id;
private string _pwd;
private string _dataBase;
private string tableName = "user";
private string configPath;
public MySqlHelp()
{
//写入配置文件中 localhost|root|123456|codedb
configPath = Application.dataPath + "/Config/Config.txt";
string configStr = File.ReadAllText(configPath);
string[] sqlStr = configStr.Split(new char[] { '|' });
InitMySql(sqlStr[0], sqlStr[1], sqlStr[2], sqlStr[3]);
}
private void InitMySql(string host, string id, string pwd, string dataBase)
{
_host = host;
_id = id;
_pwd = pwd;
_dataBase = dataBase;
OpenSqlConnection();
}
/// <summary>
/// 打开数据库连接
/// </summary>
public void OpenSqlConnection()
{
string str = "";
try
{
str = string.Format("Database={0};DataSource={1};User Id={2};Password={3};character set = utf8", _dataBase, _host, _id, _pwd, "3306");
mySqlConnection = new MySqlConnection(str);
mySqlConnection.Open();
//Debug.Log("Mysql Connection Access");
Debug.Log("数据库连接成功");
}
catch (Exception e)
{
Debug.LogError(e.Message);
//Debug.LogError("MySqlAccess", "OpenSql() 服务器连接失败。 connect str={0};Error:{1}", str, e.Message);
}
}
public DataSet Query(string format, params object[] args)
{
string query = string.Format(format, args);
//Debuger.Log("MySqlAccess", "Query() query={0}", query);
//Debug.Log(e.Message);
return ExecuteQuery(query);
}
/// <summary>
///
/// </summary>
/// <param name="sql"></param>
/// <param name="tableName">虚拟表名称</param>
/// <returns></returns>
private DataSet ExecuteQuery(string sql)
{
//Debug.Log(sql+"____");
if (mySqlConnection.State == ConnectionState.Open)
{
DataSet ds = new DataSet();
try
{
MySqlCommand mySqlCommand = new MySqlCommand(sql, mySqlConnection);
MySqlDataAdapter mySqlDataAdapter = new MySqlDataAdapter(mySqlCommand);
mySqlDataAdapter.Fill(ds);
}
catch (Exception e)
{
Debug.LogError(e.Message);
//Debuger.LogError("MySqlHelper", "ExecuteQuery() sql={0} Error:{1}", sql, e.Message);
}
return ds;
}
return null;
}
public int ExcuteReader(string sqlTxt)
{
if (mySqlConnection.State == ConnectionState.Open)
{
try
{
Debug.Log(sqlTxt);
MySqlCommand cmd = new MySqlCommand(sqlTxt, mySqlConnection);
return cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
Debug.LogError(ex.Message);
return 0;
}
}
return 0;
}
/// <summary>
/// 释放连接
/// </summary>
public void Close()
{
if (mySqlConnection != null)
{
mySqlConnection.Close();
mySqlConnection.Dispose();
mySqlConnection = null;
}
}
}
然后的话就是本项目的重点,也就是核心类(作者摸了好久,一直不懂用法):本来是有点舍不得分享,但是为了学习更多大牛的方法,豁出去了
//==========================
// - FileName: MainPanel.cs
// - Created: true.
// - CreateTime: 2020/04/26 15:27:04
// - Email: 1670328571@qq.com
// - Region: China WUHAN
// - Description: 数据库结构类
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UserDoItemData
{
//数据库正确ID
public int classID;
//数据库正确答案
public string okText;
//数据库提示信息
public string okMessage;
//用户输入的答案
public string userInputText = "";
public UserDoItemData(int id, string oktxt,string msg)
{
classID = id;
okText = oktxt;
okMessage = msg;
}
}
然后的话就是从数据库中取数据的一些方法:
private void InitEvent()
{
#region 实验
//打开数据库中的表 封装好的方法.......
DataSet dataSet = gameManager.mysqlHelp.Query("select * from maincontent", ""); //select * from classstructtable
DataTable dataTable = dataSet.Tables[0];
DataRow _dr;
for (int i = 0; i < dataTable.Rows.Count; i++)
{
_dr = dataTable.Rows[i];
for (int j = 0; j < _dr.ItemArray.Length; j++)
{
//Debug.Log(dataTable.Rows[i][j].ToString());
//将数据添加进列表
clunmList.Add(dataTable.Rows[i][j].ToString());
}
}
UserDoItemData vo_1 = null;
UserDoItemData vo_2 = null;
UserDoItemData vo_3 = null;
//第一个学生类
string[] okTextList = clunmList[1].Split('|');
string[] okMsgList = clunmList[2].Split('|');
for (int i = 0; i < okTextList.Length; i++)
{
vo_1 = new UserDoItemData(classId[0], okTextList[i], okMsgList[i]);
}
string[] okTextList1 = clunmList[5].Split('|');
string[] okMsgList1 = clunmList[6].Split('|');
for (int i = 0; i < okTextList1.Length; i++)
{
vo_2 = new UserDoItemData(classId[1], okTextList1[i], okMsgList1[i]);
}
string[] okTextList2 = clunmList[9].Split('|');
string[] okMsgList2 = clunmList[10].Split('|');
for (int i = 0; i < okTextList2.Length; i++)
{
vo_3 = new UserDoItemData(classId[2], okTextList2[i], okMsgList2[i]);
}
List<UserDoItemData> userItemList = new List<UserDoItemData>();
userItemList.Add(vo_1);
userItemList.Add(vo_2);
userItemList.Add(vo_3);
#endregion
}
分享完了以后觉得有点心痛…
最后再分享一个方法吧(好人一生平安):
//取到Config下的配置文件
private string GetConfig(string name)
{
classDrawConfig = Application.dataPath + "/Config/"+ name + ".txt";
string configStr = File.ReadAllText(classDrawConfig);
return configStr;
}