前言:數據庫在遊戲中的應用
在(客戶端)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: [email protected]
// - 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: [email protected]
// - 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;
}