今日は、Unity3D上のプロジェクトをMySQLデータベースに接続する方法を見つけます。
より正確には、ゲームオブジェクトの状態をデータベースに保存し、データベースからロードする方法を分析します。 このガイドは 、 Jonathan WoodのUnity 3.0.0f5およびMySQL 5.2.28に基づいています。 Unityの4番目のバージョンに合わせて補完および適合されています。
必要なもの:
1. Unity3D4.x。
2. MySQLデータベースへのアクセス。
3.ライブラリMySql.Data.dll。
プロジェクトフォルダに、MySQL.Data.dllライブラリを配置する必要があるライブラリディレクトリを作成する必要があります。 このアーカイブからダウンロードできますが、MySQLが既にインストールされている場合は、c:\ Program Files(x86)\ MySQL \ MySQL Connector Net 6.0.3 \ Assemblies \からコピーできます。
アセンブリバージョンの互換性の問題を回避し、数時間と神経を節約するため( Joelのおかげ)、互換性APIレベルを編集->プロジェクト設定->プレーヤー->最適化-> Api互換性レベル= .NET 2.0に設定します。
予備作業:
1.保存する必要のあるオブジェクトには、「保存可能」タグが付いています。
2.オブジェクトに関する情報を保存するテーブルをデータベースに作成します。
新しいライブラリを使用するには、スクリプトの先頭に追加します。
using MySql.Data; using MySql.Data.MySqlClient;
また、接続パラメーターを変数に書き込むことを忘れないでください。
// MySQL string constr = "Server=localhost;Database=demo;User ID=demo;Password=demo;Pooling=true;CharSet=utf8;";
オブジェクトに関する情報が保存される構造を作成します。
// string ID, Name, levelname, objectType; float posx, posy, posz, tranx, trany, tranz; // public struct data { public int UID; public string ID, Name, levelname, objectType; public float posx, posy, posz, tranx, trany, tranz; } // List<data> _GameItems;
起動時に、スクリプトはデータベースに接続し、オフにすると切断されます。
void Awake() { try { // con = new MySqlConnection(constr); // , con.Open(); Debug.Log("Connection State: " + con.State); } catch (IOException ex) {Debug.Log(ex.ToString());} } void OnApplicationQuit() { Debug.Log("killing con"); if (con != null) { // , : // if (con.State != ConnectionState.Closed) // - if (con.State.ToString()!="Closed") con.Close(); con.Dispose(); } }
ステージ上のオブジェクトの操作を担当する2つの手順があります。
prepDate-データベースに書き込むためのデータを準備します
/// void prepData() { bodies = GameObject.FindGameObjectsWithTag("Savable"); _GameItems = new List<data>(); data itm; foreach (GameObject body in bodies) { itm = new data(); itm.ID = body.name + "_" + body.GetInstanceID(); itm.Name = body.name; itm.levelname = Application.loadedLevelName; itm.objectType = body.name.Replace("(Clone)", ""); itm.posx = body.transform.position.x; itm.posy = body.transform.position.y; itm.posz = body.transform.position.z; itm.tranx = body.transform.rotation.x; itm.trany = body.transform.rotation.y; itm.tranz = body.transform.rotation.z; _GameItems.Add(itm); } Debug.Log("Items in collection: " + _GameItems.Count); } }
loadDate-シーンにオブジェクトをロードします
/// void loadData() { // bodies = GameObject.FindGameObjectsWithTag("Savable"); DestroyObject(bodies); // if (_GameItems != null) { if (_GameItems.Count > 0) { foreach (data itm in _GameItems) { if (itm.objectType="CUBE") {Instantiate(mCUBE, new Vector3(itm.posx, itm.posy , itm.posz),Quaternion.Euler(itm.tranx, itm.trany, itm.tranz));} else if (itm.objectType="SPHERE") {Instantiate(mSPHERE, new Vector3(itm.posx, itm.posy , itm.posz),Quaternion.Euler(itm.tranx, itm.trany, itm.tranz));} else if (itm.objectType="TRIANGLE") {Instantiate(mTRIANGLE, new Vector3(itm.posx, itm.posy , itm.posz),Quaternion.Euler(itm.tranx, itm.trany, itm.tranz));} } } } } }
また、データベースの操作を担当する4つの主要な手順:
InsertEntries-テーブルに新しいレコードを挿入します。
// void InsertEntries() { prepData(); string query = string.Empty; // try { query = "INSERT INTO demo_table (ID, Name, levelname, objectType, posx, posy, posz, tranx, trany, tranz) VALUES (?ID, ?Name, ?levelname, ?objectType, ?posx, ?posy, ?posz, ?tranx, ?trany, ?tranz)"; if (con.State.ToString()!="Open") con.Open(); using (con) { foreach (data itm in _GameItems) { using (cmd = new MySqlCommand(query, con)) { MySqlParameter oParam = cmd.Parameters.Add("?ID", MySqlDbType.VarChar); oParam.Value = itm.ID; MySqlParameter oParam1 = cmd.Parameters.Add("?Name", MySqlDbType.VarChar); oParam1.Value = itm.Name; MySqlParameter oParam2 = cmd.Parameters.Add("?levelname", MySqlDbType.VarChar); oParam2.Value = itm.levelname; MySqlParameter oParam3 = cmd.Parameters.Add("?objectType", MySqlDbType.VarChar); oParam3.Value = itm.objectType; MySqlParameter oParam4 = cmd.Parameters.Add("?posx", MySqlDbType.Float); oParam4.Value = itm.posx; MySqlParameter oParam5 = cmd.Parameters.Add("?posy", MySqlDbType.Float); oParam5.Value = itm.posy; MySqlParameter oParam6 = cmd.Parameters.Add("?posz", MySqlDbType.Float); oParam6.Value = itm.posz; MySqlParameter oParam7 = cmd.Parameters.Add("?tranx", MySqlDbType.Float); oParam7.Value = itm.tranx; MySqlParameter oParam8 = cmd.Parameters.Add("?trany", MySqlDbType.Float); oParam8.Value = itm.trany; MySqlParameter oParam9 = cmd.Parameters.Add("?tranz", MySqlDbType.Float); oParam9.Value = itm.tranz; cmd.ExecuteNonQuery(); } } } } catch (IOException ex) { Debug.Log(ex.ToString()); } finally {} }
UpdateEntries-テーブル内の既存のレコードを更新します。
// void UpdateEntries() { prepData(); string query = string.Empty; // try { query = "UPDATE demo_table SET ID=?ID, Name=?Name, levelname=?levelname, objectType=?objectType, posx=?posx, posy=?posy, posz=?posz, tranx=?tranx, trany=?trany, tranz=?tranz WHERE iddemo_table=?UID"; if (con.State.ToString()!="Open") con.Open(); using (con) { foreach (data itm in _GameItems) { using (cmd = new MySqlCommand(query, con)) { MySqlParameter oParam = cmd.Parameters.Add("?ID", MySqlDbType.VarChar); oParam.Value = itm.ID; MySqlParameter oParam1 = cmd.Parameters.Add("?Name", MySqlDbType.VarChar); oParam1.Value = itm.Name; MySqlParameter oParam2 = cmd.Parameters.Add("?levelname", MySqlDbType.VarChar); oParam2.Value = itm.levelname; MySqlParameter oParam3 = cmd.Parameters.Add("?objectType", MySqlDbType.VarChar); oParam3.Value = itm.objectType; MySqlParameter oParam4 = cmd.Parameters.Add("?posx", MySqlDbType.Float); oParam4.Value = itm.posx; MySqlParameter oParam5 = cmd.Parameters.Add("?posy", MySqlDbType.Float); oParam5.Value = itm.posy; MySqlParameter oParam6 = cmd.Parameters.Add("?posz", MySqlDbType.Float); oParam6.Value = itm.posz; MySqlParameter oParam7 = cmd.Parameters.Add("?tranx", MySqlDbType.Float); oParam7.Value = itm.tranx; MySqlParameter oParam8 = cmd.Parameters.Add("?trany", MySqlDbType.Float); oParam8.Value = itm.trany; MySqlParameter oParam9 = cmd.Parameters.Add("?tranz", MySqlDbType.Float); oParam9.Value = itm.tranz; cmd.ExecuteNonQuery(); } } } } catch (IOException ex) {Debug.Log(ex.ToString());} finally {} }
DeleteEntries-テーブルからレコードを削除します。
// void DeleteEntries() { string query = string.Empty; // try { // ID , //----------------------------------------------------------------------- // query = "DELETE FROM demo_table WHERE iddemo_table=?UID"; // MySqlParameter oParam = cmd.Parameters.Add("?UID", MySqlDbType.Int32); // oParam.Value = 0; //----------------------------------------------------------------------- query = "DELETE FROM demo_table WHERE iddemo_table"; if (con.State.ToString()!="Open") con.Open(); using (con) { using (cmd = new MySqlCommand(query, con)) { cmd.ExecuteNonQuery(); } } } catch (IOException ex) {Debug.Log(ex.ToString());} finally {} }
ReadEntries-テーブルからすべてのレコードを読み取ります。
// void ReadEntries() { string query = string.Empty; if (_GameItems == null) _GameItems = new List<data>(); if (_GameItems.Count > 0) _GameItems.Clear(); // try { query = "SELECT * FROM view_demo"; if (con.State.ToString()!="Open") con.Open(); using (con) { using (cmd = new MySqlCommand(query, con)) { rdr = cmd.ExecuteReader(); if(rdr.HasRows) while (rdr.Read()) { data itm = new data(); itm.UID = int.Parse(rdr["iddemo_table"].ToString()); itm.ID = rdr["ID"].ToString(); itm.levelname = rdr["levelname"].ToString(); itm.Name = rdr["Name"].ToString(); itm.objectType = rdr["objectType"].ToString(); itm.posx = float.Parse(rdr["posx"].ToString()); itm.posy = float.Parse(rdr["posy"].ToString()); itm.posz = float.Parse(rdr["posz"].ToString()); itm.tranx = float.Parse(rdr["tranx"].ToString()); itm.trany = float.Parse(rdr["trany"].ToString()); itm.tranz = float.Parse(rdr["tranz"].ToString()); _GameItems.Add(itm); } rdr.Dispose(); } } } catch (IOException ex) {Debug.Log(ex.ToString());} finally {} }
あとは、シーンをロードおよび保存するためのボタンを2つ作成するだけです。
// void OnGUI() { if (GUI.Button(new Rect(10, 70, 50, 30), "Save") && !saving) { saving = true; // DeleteEntries(); // InsertEntries(); // ID saving = false; } if (GUI.Button(new Rect(10, 110, 50, 30), "Load") && !loading) { loading = true; // ReadEntries(); // loadData(); // LogGameItems(); loading = false; } }
それは基本的にそれです。 コメントやコメントを歓迎します。
スクリプト全体
using UnityEngine; using MySql.Data; using MySql.Data.MySqlClient; using System.IO; using System.Collections; using System.Collections.Generic; public class MySQLCS : MonoBehaviour { public GameObject mCUBE; public GameObject mSPHERE; public GameObject mTRIANGLE; bool saving = false; bool loading = false; // MySQL string constr = "Server=localhost;Database=demo;User ID=demo;Password=demo;Pooling=true;CharSet=utf8;"; // MySqlConnection con = null; // MySqlCommand cmd = null; // MySqlDataReader rdr = null; // MySqlError er = null; // GameObject[] bodies; // string ID, Name, levelname, objectType; float posx, posy, posz, tranx, trany, tranz; // public struct data { public int UID; public string ID, Name, levelname, objectType; public float posx, posy, posz, tranx, trany, tranz; } // List<data> _GameItems; void Awake() { try { // con = new MySqlConnection(constr); // , con.Open(); Debug.Log("Connection State: " + con.State); } catch (IOException ex) {Debug.Log(ex.ToString());} } void OnApplicationQuit() { Debug.Log("killing con"); if (con != null) { // , : // if (con.State != ConnectionState.Closed) // - if (con.State.ToString()!="Closed") con.Close(); con.Dispose(); } } // Use this for initialization void Start() { } // Update is called once per frame void Update() { } // void OnGUI() { if (GUI.Button(new Rect(10, 70, 50, 30), "Save") && !saving) { saving = true; // DeleteEntries(); // InsertEntries(); // ID saving = false; } if (GUI.Button(new Rect(10, 110, 50, 30), "Load") && !loading) { loading = true; // ReadEntries(); // loadData(); // LogGameItems(); loading = false; } } // void InsertEntries() { prepData(); string query = string.Empty; // try { query = "INSERT INTO demo_table (ID, Name, levelname, objectType, posx, posy, posz, tranx, trany, tranz) VALUES (?ID, ?Name, ?levelname, ?objectType, ?posx, ?posy, ?posz, ?tranx, ?trany, ?tranz)"; if (con.State.ToString()!="Open") con.Open(); using (con) { foreach (data itm in _GameItems) { using (cmd = new MySqlCommand(query, con)) { MySqlParameter oParam = cmd.Parameters.Add("?ID", MySqlDbType.VarChar); oParam.Value = itm.ID; MySqlParameter oParam1 = cmd.Parameters.Add("?Name", MySqlDbType.VarChar); oParam1.Value = itm.Name; MySqlParameter oParam2 = cmd.Parameters.Add("?levelname", MySqlDbType.VarChar); oParam2.Value = itm.levelname; MySqlParameter oParam3 = cmd.Parameters.Add("?objectType", MySqlDbType.VarChar); oParam3.Value = itm.objectType; MySqlParameter oParam4 = cmd.Parameters.Add("?posx", MySqlDbType.Float); oParam4.Value = itm.posx; MySqlParameter oParam5 = cmd.Parameters.Add("?posy", MySqlDbType.Float); oParam5.Value = itm.posy; MySqlParameter oParam6 = cmd.Parameters.Add("?posz", MySqlDbType.Float); oParam6.Value = itm.posz; MySqlParameter oParam7 = cmd.Parameters.Add("?tranx", MySqlDbType.Float); oParam7.Value = itm.tranx; MySqlParameter oParam8 = cmd.Parameters.Add("?trany", MySqlDbType.Float); oParam8.Value = itm.trany; MySqlParameter oParam9 = cmd.Parameters.Add("?tranz", MySqlDbType.Float); oParam9.Value = itm.tranz; cmd.ExecuteNonQuery(); } } } } catch (IOException ex) { Debug.Log(ex.ToString()); } finally {} } // void UpdateEntries() { prepData(); string query = string.Empty; // try { query = "UPDATE demo_table SET ID=?ID, Name=?Name, levelname=?levelname, objectType=?objectType, posx=?posx, posy=?posy, posz=?posz, tranx=?tranx, trany=?trany, tranz=?tranz WHERE iddemo_table=?UID"; if (con.State.ToString()!="Open") con.Open(); using (con) { foreach (data itm in _GameItems) { using (cmd = new MySqlCommand(query, con)) { MySqlParameter oParam = cmd.Parameters.Add("?ID", MySqlDbType.VarChar); oParam.Value = itm.ID; MySqlParameter oParam1 = cmd.Parameters.Add("?Name", MySqlDbType.VarChar); oParam1.Value = itm.Name; MySqlParameter oParam2 = cmd.Parameters.Add("?levelname", MySqlDbType.VarChar); oParam2.Value = itm.levelname; MySqlParameter oParam3 = cmd.Parameters.Add("?objectType", MySqlDbType.VarChar); oParam3.Value = itm.objectType; MySqlParameter oParam4 = cmd.Parameters.Add("?posx", MySqlDbType.Float); oParam4.Value = itm.posx; MySqlParameter oParam5 = cmd.Parameters.Add("?posy", MySqlDbType.Float); oParam5.Value = itm.posy; MySqlParameter oParam6 = cmd.Parameters.Add("?posz", MySqlDbType.Float); oParam6.Value = itm.posz; MySqlParameter oParam7 = cmd.Parameters.Add("?tranx", MySqlDbType.Float); oParam7.Value = itm.tranx; MySqlParameter oParam8 = cmd.Parameters.Add("?trany", MySqlDbType.Float); oParam8.Value = itm.trany; MySqlParameter oParam9 = cmd.Parameters.Add("?tranz", MySqlDbType.Float); oParam9.Value = itm.tranz; cmd.ExecuteNonQuery(); } } } } catch (IOException ex) {Debug.Log(ex.ToString());} finally {} } // void DeleteEntries() { string query = string.Empty; // try { // ID , //----------------------------------------------------------------------- // query = "DELETE FROM demo_table WHERE iddemo_table=?UID"; // MySqlParameter oParam = cmd.Parameters.Add("?UID", MySqlDbType.Int32); // oParam.Value = 0; //----------------------------------------------------------------------- query = "DELETE FROM demo_table WHERE iddemo_table"; if (con.State.ToString()!="Open") con.Open(); using (con) { using (cmd = new MySqlCommand(query, con)) { cmd.ExecuteNonQuery(); } } } catch (IOException ex) {Debug.Log(ex.ToString());} finally {} } // void ReadEntries() { string query = string.Empty; if (_GameItems == null) _GameItems = new List<data>(); if (_GameItems.Count > 0) _GameItems.Clear(); // try { query = "SELECT * FROM view_demo"; if (con.State.ToString()!="Open") con.Open(); using (con) { using (cmd = new MySqlCommand(query, con)) { rdr = cmd.ExecuteReader(); if(rdr.HasRows) while (rdr.Read()) { data itm = new data(); itm.UID = int.Parse(rdr["iddemo_table"].ToString()); itm.ID = rdr["ID"].ToString(); itm.levelname = rdr["levelname"].ToString(); itm.Name = rdr["Name"].ToString(); itm.objectType = rdr["objectType"].ToString(); itm.posx = float.Parse(rdr["posx"].ToString()); itm.posy = float.Parse(rdr["posy"].ToString()); itm.posz = float.Parse(rdr["posz"].ToString()); itm.tranx = float.Parse(rdr["tranx"].ToString()); itm.trany = float.Parse(rdr["trany"].ToString()); itm.tranz = float.Parse(rdr["tranz"].ToString()); _GameItems.Add(itm); } rdr.Dispose(); } } } catch (IOException ex) {Debug.Log(ex.ToString());} finally {} } /// void LogGameItems() { if (_GameItems != null) { if (_GameItems.Count > 0) { foreach (data itm in _GameItems) { Debug.Log("UID: " + itm.UID); Debug.Log("ID: " + itm.ID); Debug.Log("levelname: " + itm.levelname); Debug.Log("Name: " + itm.Name); Debug.Log("objectType: " + itm.objectType); Debug.Log("posx: " + itm.posx); Debug.Log("posy: " + itm.posy); Debug.Log("posz: " + itm.posz); Debug.Log("tranx: " + itm.tranx); Debug.Log("trany: " + itm.trany); Debug.Log("tranz: " + itm.tranz); } } } } /// void prepData() { bodies = GameObject.FindGameObjectsWithTag("Savable"); _GameItems = new List<data>(); data itm; foreach (GameObject body in bodies) { itm = new data(); itm.ID = body.name + "_" + body.GetInstanceID(); itm.Name = body.name; itm.levelname = Application.loadedLevelName; itm.objectType = body.name.Replace("(Clone)", ""); itm.posx = body.transform.position.x; itm.posy = body.transform.position.y; itm.posz = body.transform.position.z; itm.tranx = body.transform.rotation.x; itm.trany = body.transform.rotation.y; itm.tranz = body.transform.rotation.z; _GameItems.Add(itm); } Debug.Log("Items in collection: " + _GameItems.Count); } } /// void loadData() { // bodies = GameObject.FindGameObjectsWithTag("Savable"); DestroyObject(bodies); // if (_GameItems != null) { if (_GameItems.Count > 0) { foreach (data itm in _GameItems) { if (itm.objectType="CUBE") {Instantiate(mCUBE, new Vector3(itm.posx, itm.posy , itm.posz),Quaternion.Euler(itm.tranx, itm.trany, itm.tranz));} else if (itm.objectType="SPHERE") {Instantiate(mSPHERE, new Vector3(itm.posx, itm.posy , itm.posz),Quaternion.Euler(itm.tranx, itm.trany, itm.tranz));} else if (itm.objectType="TRIANGLE") {Instantiate(mTRIANGLE, new Vector3(itm.posx, itm.posy , itm.posz),Quaternion.Euler(itm.tranx, itm.trany, itm.tranz));} } } } } }