【unity】利用sqlite制作排行榜

同学做项目的时候,想采用sqlite来制作排行榜。好吧,对于数据库,我只是简单的接触过,并不熟悉。所以今天花了半天多的时间来温习了下这部分知识。。。当然了,我觉得吧,能跟其他知识点结合起来运用,才能最大限度的接受它,了解它。所以呢,本篇文章,在利用本地数据库的同时,利用UGUI简单的制作一个排行榜吧。


     第一部分、数据库管理
     我在网上找资料的时候,发现关于数据库的东西,都已经是很以前写的了。。弄的我晕晕乎乎的。
总结了一番,加上自己当时学习时的领悟,下面来一步一步说明我的做法。如有错误,希望指正。
     啊,首先,你得安装个SQlite Manager,我用的是火狐。

打开它,新建一个.sqlite的文件到你的工程asset文件夹下。(路径一定要是工程下的.sqlite,否则数据是读不到的)。

在此我说明一点,我之前刚接触数据库的时候用的是sqlite3,现在反而用了sqlite,其实我觉得没什么差别,可能在sql语句上有所区别吧。关于两者区别,我也没细研究。所以请各位去网上找吧(- -。。。)

     之后呢,我需要两个文件,

    这两个文件都可以在Unity的安装包里找到的,

     准备工作就这样了。下面我来说我的一个相对简单容易理解的数据库管理脚本。代码如下:
using System ;
using UnityEngine;
using System.Collections.Generic ;
using Mono.Data .Sqlite;
using System.Collections;
public class DBmanager {
  
   /// <summary>
     ///单例模式
     /// </summary>
    
      private static DBmanager instance;

     public static DBmanager Instance
     {
          get
          {
               if(instance == null )
               {
                    instance = new DBmanager ();
               }
               return instance ;
          }
     }

     private DBmanager (){}

     //连接
     private SqliteConnection dbConnect;
     //指令
     private SqliteCommand dbCommand;
     //写操作
     private SqliteDataReader dbDataReader;

     public  Dictionary <string ,List <string >> dbDic;

     /// <summary>
     /// Opens the sql.
     /// </summary>
     public void OpenSql()
     {
          try
          {
               string path = "Data Source = " + Application.dataPath + "/rank.sqlite";
               dbConnect = new SqliteConnection (path );
               dbConnect.Open ();
               dbCommand = new SqliteCommand ();
               dbCommand.Connection = dbConnect ;
          }
          catch (Exception ex )
          {
               Debug.Log ("Exception is :" + ex.ToString ());
          }
     }
     /// <summary>
     /// Enquiries the sql.
     /// 读取数据
     /// </summary>
     /// <returns>返回数据集</returns>
     /// <param name="str">sql命令</param>
     public  Dictionary <string ,List <string >> EnquirySql(string str)
     {

          dbDic = new Dictionary<string, List<string>> ();

          try
          {
               dbCommand.CommandText = str ;
               dbDataReader = dbCommand.ExecuteReader ();
              
               while (dbDataReader.Read ())
               {
                    for ( int i = 0 ; i < dbDataReader.FieldCount ; i ++)
                    {
                         string keyStr = dbDataReader.GetName (i);
                         string valueStr = dbDataReader.GetValue (i).ToString ();

                         if(!dbDic  .ContainsKey(keyStr ))
                         {
                              dbDic [keyStr ] = new List<string> ();
                              dbDic [keyStr ].Add (valueStr );
                         }
                         else
                         {
                              dbDic [keyStr ].Add (valueStr );
                         }
                    }
               }
               //记得读取完关上它 - -
               dbDataReader .Close ();
               return dbDic ;
          }
          catch (Exception ex)
          {
               Debug.Log ("Exception is :" + ex.ToString ());
               return dbDic ;
          }
     }


     /// <summary>
     ///执行增删改查操作
     /// </summary>
     /// <returns>The sql.</returns>
     /// <param name="str">String.</param>
     public     int ExecuteSql(string str)
     {
          try
          {
               dbCommand.CommandText = str;
               return dbCommand.ExecuteNonQuery ();
          }
          catch (Exception ex)
          {
               Debug.Log("Exception is :" + ex.ToString ());
               return 0;
          }
     }

     /// <summary>
     ///关闭数据库
     /// </summary>
     public void CloseSql()
     {
          dbConnect.Close ();
          dbCommand.Dispose();
     }
 }



     对于我写的这个脚本,其实并没有什么太难的地方。写了4个方法,打开数据库连接,查询数据库,增删改查数据库,关闭数据库。唯一注意的就是,这个脚本是不挂在任何物体上的。(把继承于MonoBehaviour删掉)。另外,在查询数据库的地方我利用了字典方便管理我的数据库的数据。

  
   第二部分 利用UGUI制作排行榜
     
     最近蛮牛有好些UGUI的文章出现,我也来凑个热闹。。。。。。。。(其实我对UGUI比NGUI熟悉。。。谁让我这个后来人接触UNITY的时候,UGUI已经出了呢。。。。)

     这个我一步一步来吧。首先新建一个Panel,在Panel下新建一个空物体,将它命名为list,作为我们存放排行信息的一个父物体。通过锚点设置给list大小设置为跟信息长宽相同大小。(下图)再在list下新建一个空物体,命名为data,用来当做我们每一条排行信息的父物体。并将之拉成预设体。在Panel上加上一个Scroll Rect组件(记得把list拖入Content中),在list上加上一个vertical Layout Group 以进行垂直的自动布局。如图:
为了模拟游戏的开始结束,我建了两个Button,分别假设为开始游戏的时候和游戏结束的时候。我现在的Game试图如下:

不要在乎美工这些细节。。。我就是来实现功能的- -。。。。之后就是代码部分啦。思路是,依靠循环生成我的data数据,想生成几个就循环几次。之后,因为List有自动排序功能,所以要控制list的高度,让他随着数据的增加,高度也增加。
  

[code]csharpcode:

public class Creat : MonoBehaviour {

     /// <summary>
     ///该脚本挂到list上
     /// </summary>


     private RectTransform rt;
     //记录高度
     private float height;

     void Start () {
          rt = GetComponent <RectTransform >();
          //生成5条数据
          for ( int i = 0 ; i < 5 ; i ++)
          {
               GameObject go =Instantiate (  Resources .Load ("Data")) as GameObject ;
          //生成的数据为List的子物体
               go.transform.SetParent (transform );
               //list的高度变化
               height += go.GetComponent <RectTransform >().sizeDelta.y;
          }
          //将height赋值给List
          rt.sizeDelta = new Vector2 (rt.sizeDelta.x , height );
     }

以上是一个简化版的排行榜,并没有将数据存放进去。
那么,下面我们的工作其实就是将数据库与UGUI制作的排行榜结合起来。

第三部分:排行榜与数据库融合
    
我是做了一个模拟游戏进度的两个Button,但实际上可以自己开动大脑来实现一下这两部分功能,所以在这个部分,我就直接上代码了。如果有什么问题,请留言提问。

[code]csharpcode:

using UnityEngine;
using System.Collections.Generic ;
using UnityEngine.UI;
public class rankList : MonoBehaviour {

	//防止点击Button重复生成data采用的bool
	private bool isCreatGoOn;

	//list的高度
	private  float height;
	private  RectTransform rt;

	//生成的data放入数组方便统一管理
	private GameObject[] dataArray; 
	
	public Text nameText;
	public Text scoreText;

	void Start () {
		rt = GetComponent <RectTransform >();
		isCreatGoOn = true  ;
	}

	/// <summary>
	/// 制作排行榜的方法
	/// </summary>
	/// <param name="datacount">多少个数据</param>
	public void RankList(int datacount )
	{
		for ( int i = 0 ; i < datacount  ; i ++)
		{
			nameText.text = DBmanager.Instance.dbDic ["Name"][i];
			scoreText .text = DBmanager .Instance .dbDic  ["score"][i];
			 dataArray[i ]   =  Instantiate ( Resources .Load ("data")) as GameObject ;
			if(dataArray[i]  != null )
			{
				dataArray[i] .transform.SetParent (this.transform );
			}
			height += 100;
		}

		rt.sizeDelta = new Vector2 (rt.sizeDelta.x , height );
	}


	/// <summary>
	///begin点击Button事件 
	/// </summary>
	public void GameBegin()
	{
		print ("gp");
		if(isCreatGoOn )
		{
			DBmanager.Instance.OpenSql ();
			DBmanager.Instance.EnquirySql ("select * from information order by score desc");

			//此时千万不要写成DBmanager.Instance.dbDic.Count  ,因为要获取的是行数,而不是键值对的个数
			List <string > tempList = DBmanager.Instance.dbDic["Name"] ;

			dataArray = new GameObject[tempList.Count ];	 
			RankList (tempList.Count );
			
			DBmanager.Instance.CloseSql ();
			isCreatGoOn = false ;
		}

	}

	/// <summary>
	/// Games the over Button点击事件.
	/// </summary>
	public void GameOver()
	{
		isCreatGoOn = true ;
		for( int i = 0 ; i < dataArray.Length ; i ++)
		{
			Destroy (dataArray[i].gameObject );
			//结束游戏要还原height值,否则会导致list自动排序出错
			height -=dataArray [i].GetComponent <RectTransform >().sizeDelta .y;
		}
		ChangeRank ("小贝",14,95);	
		rt.sizeDelta = new Vector2 (rt.sizeDelta.x , height );
	}

	/// <summary>
	///测试下。。。。 
	/// </summary>
	/// <param name="name">Name.</param>
	/// <param name="age">Age.</param>
	/// <param name="score">Score.</param>

	public void ChangeRank(string name , int age , float score)
	{
		DBmanager.Instance.OpenSql ();
		DBmanager.Instance.ExecuteSql("insert into information  values(' " + name +" '," + age.ToString () + "," + score.ToString () + ")" );
		DBmanager.Instance.EnquirySql ("delete from information where rowid in (select rowid from information order by score asc limit 0 ,1)");
	}
}



说明一下我的运行结果,我在数据库的时候,先添加了5条数据:

     当我点击开始游戏按钮,我的排名是这样的:

当我结束的时候,玩家会有个成绩,我写了个测试方法,就是添加一条数据进去,之后排序后删掉分数最低的数据:

     
     其实对于最后一个为了测试的方法,这里面的东西其实还是有一点绕的,一个是关于string与sqlite的TEXT文本的转换,另一个就是sql的复合语句的运用。
     对于sqlite语句,网上真的是很多,所以我就不说了,我更喜欢做一点小东西出来分享,而不是太基础的死知识。~

     我还需要说明一点,对于PC端,这么写是没问题的,但是如果放在安卓和ios上,还是会有一些新的问题的,对于在手机上使用sqlite,雨松大神有两篇博文专门写这个的。下面附上链接:


     好了今天就这样吧,其实这些东西还是花了我不少功夫的,但是还是有一些小问题的。(比如UGUI适配我没有弄),不过今天我确实学到了不少东西哈。
    希望对跟我类似刚接触Untiy的盆友有所帮助,同时也希望大神们给予指正,帮助。

【本人首次发表于蛮牛,系本人原创】
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wonnayov/article/details/47276021
个人分类: Unity
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭