1、功能:在一个UIPanel上动态加载若干个Items,每一个Item包含一个UIButton和UISprite。然后每一行放置5个。如果超出UIPanel范围的Item则可以拖动它来显示。按钮的标签内容和精灵的图片根据数据库的内容来动态显示。
2、实现的步骤:
1)导入NGUI资源包:我这里使用的是无水印的,来自互联网上各路好汉的分享,大家可以在百度谷歌上去找。当然免费版的也可以,跟我的图示当中会有些差异,大家注意了。导入NGUI成功后就会发现Unity Editor导航菜单栏中多了一项“NGUI”菜单。(有NGUI的同学就可以跳过这一步了)
2)制作图集(UIAtlas):首先在网上找一些图片素材,最好是.jpg或者.png格式的,大小无要求。分别命名后一起存入Assets/MyAtlas目录下,当然你可以把MyAtlas换成你所喜欢的。在Unity Editor的Project视图中选中刚刚导入进来的所有图片,然后选择导航菜单中的“NGUI|Open the Atlas Maker”。如图所示:
命名后点击“Create”即可创建自己的Atlas。当然,可以用NGUI做好的图集,只不过这样图片差异太大,风格不统一。
3)创建Sqlite数据库:首先你得下载Sqlite Expert,我下载的是 Personal版本。免费版的下载地址为:http://www.sqliteexpert.com/download.html。安装运行之。然后找到正确Application.persistantDataPath的位置,可以通过Debug.Log一下得到,然后在该路径下创建数据库,取名“tzzm.db”。新建一个表,取名“Animal”,添加两个字段,id(INT)和name(CHAR),添加完之后点击“Apply”。在Data视图中按图集“Animal Atlas”中图片的顺序添加记录。
参考雨松MOMO的博客,创建DbAccess.cs脚本。引入“System.Data.dll”和“Mono.Data.Sqlite.dll”,放置在“Assets/Plugins”目录下,注意这个名字不能更改。雨松MOMO博客地址:http://www.xuanyusong.com/archives/831
DbAccess.cs脚本的代码如下(这个脚本不要挂在任何对象上):
1 using UnityEngine; 2 using System; 3 using System.Collections; 4 using Mono.Data.Sqlite; 5 6 public class DbAccess 7 { 8 private SqliteConnection dbConnection; 9 private SqliteCommand dbCommand; 10 private SqliteDataReader reader; 11 12 public DbAccess(string connectionString) 13 { 14 OpenDB(connectionString); 15 } 16 17 public DbAccess() 18 { 19 20 } 21 22 public void OpenDB(string connectionString) 23 { 24 try 25 { 26 dbConnection=new SqliteConnection(connectionString); 27 dbConnection.Open(); 28 } 29 catch(Exception e) 30 { 31 Debug.Log(e.ToString()); 32 } 33 } 34 35 public void CloseSqlConnection() 36 { 37 if(dbCommand!=null) 38 { 39 dbCommand.Dispose(); 40 } 41 dbCommand=null; 42 if(reader!=null) 43 { 44 reader.Dispose(); 45 } 46 reader=null; 47 if(dbConnection!=null) 48 { 49 dbConnection.Dispose(); 50 } 51 dbConnection=null; 52 } 53 54 public SqliteDataReader ExecuteQuery(string sqlQuery) 55 { 56 dbCommand=dbConnection.CreateCommand(); 57 dbCommand.CommandText=sqlQuery; 58 reader=dbCommand.ExecuteReader(); 59 return reader; 60 } 61 62 public SqliteDataReader ReadFullTable(string tableName) 63 { 64 string query="SELECT * FROM " + tableName; 65 return ExecuteQuery(query); 66 } 67 68 public SqliteDataReader InsertInto(string tableName,string[] values) 69 { 70 string query="INSERT INTO " + tableName + " VALUES (" + values[0]; 71 for(int i=1;i<values.Length;i++) 72 { 73 query+=", " + values[i]; 74 } 75 query +=")"; 76 return ExecuteQuery(query); 77 } 78 79 public SqliteDataReader UpdateInto(string tableName,string[] cols,string[] colsvalues,string selectedKey,string selectedValue) 80 { 81 string query="UPDATE " + tableName + " SET " + cols[0] + " = " + colsvalues[0]; 82 for(int i=1;i<colsvalues.Length;i++) 83 { 84 query+=", " + cols[i] + " = " + colsvalues[i]; 85 } 86 query+=" WHERE " +selectedKey + " = " + selectedValue + " "; 87 return ExecuteQuery(query); 88 } 89 90 public SqliteDataReader Delete(string tableName,string[] cols,string[] colsvalues) 91 { 92 string query="DELETE FROM " + tableName + " WHERE " + cols[0] + " =" + colsvalues[0]; 93 for(int i=1;i<colsvalues.Length;i++) 94 { 95 query+=" OR" + cols[i] + " = " + colsvalues[i]; 96 } 97 return ExecuteQuery(query); 98 } 99 100 public SqliteDataReader InsertIntoSpecific(string tableName,string[] cols,string[] values) 101 { 102 if(cols.Length!=values.Length) 103 { 104 throw new SqliteException("cols.Length!=values.Length"); 105 } 106 string query="INSERT INTO " + tableName + "(" + cols[0]; 107 for(int i=1;i<cols.Length;i++) 108 { 109 query+=", " + cols[i]; 110 } 111 query+=")"; 112 return ExecuteQuery(query); 113 } 114 115 public SqliteDataReader DeleteContents(string tableName) 116 { 117 string query="DELETE FROM " + tableName; 118 return ExecuteQuery(query); 119 } 120 121 public SqliteDataReader CreateTable(string name,string[] cols,string[] colsTypes) 122 { 123 if(cols.Length!=colsTypes.Length) 124 { 125 throw new SqliteException("cols.Length!=colsTypes.Length"); 126 } 127 string query="CREATE TABLE " + name + "(" + cols[0] + " " + colsTypes[0]; 128 for(int i=1;i<cols.Length;i++) 129 { 130 query+=", " + cols[i] + " " + colsTypes[i]; 131 } 132 query+=")"; 133 return ExecuteQuery(query); 134 } 135 136 public SqliteDataReader SelectWhere(string tableName,string[] items,string[] cols,string[] operations,string[] values) 137 { 138 if(cols.Length!=operations.Length || operations.Length!=values.Length) 139 { 140 throw new SqliteException("cols.Length!=operations.Length || operations.Length!=values.Length"); 141 } 142 string query="SELECT " + items[0]; 143 for(int i=1;i<items.Length;i++) 144 { 145 query+=", " + items[i]; 146 } 147 query+=" FROM " + tableName + " WHERE " +cols[0] + operations[0] + "'" + values[0] + "' "; 148 for(int i=1;i<cols.Length;i++) 149 { 150 query += " AND " + cols[i] + operations[i] + "'" + values[0] + "' "; 151 } 152 return ExecuteQuery(query); 153 } 154 }
完成脚本后我们再进行下一步。
4)制作NGUI(最核心的步骤):
一、新建一个空场景,删掉原来的Main Camera。点击“NGUI|Open the UI Wizard”,点击“Create”。选中Panel,将其clipping属性改为“Soft Clip”,size设为“700,400”,softness设置为“10,10”。然后为其添加一个UIDraggablePanel组件,勾选Restrict Within Panel选项,Scroll Wheel Factor设为“-2”。其它属性保持默认。
二、创建一个空对象,更名为UIItable,并作为Panel的子对象,reset该空对象。为其添加UITable的组件,colunms设为4,direction设为down,padding设为“10,10”,勾选hide inactive和keep in panel属性。
三、再创建一个空对象,更名为UIItem,作为UITable的子对象,reset该空对象。为其添加一个Box Collider组件,并将其size属性设为“200,200”,再添加一个UIDragPanelContents组件。
四、在UIItem对象下创建各种wedgits,如UIButton,UISprite之类的,制作好一个之后运行看效果是否能够达到预期,即是否能拖动并在边界弹回。如果发生按钮不能点击的情况,请设置两个colliders的相对位置。调整好UIItem之后,在Project视图下创建一个新的prefab,命名为item,将Hierarchy视图中的UIItem拖入item预设中。
5)为摄像机添加脚本Test.cs,其代码如下:
1 using UnityEngine; 2 using System.Collections; 3 using System.Data; 4 using Mono.Data.Sqlite; 5 6 public class s1 : MonoBehaviour { 7 string LevelName="Animal"; 8 public GameObject item; 9 public Transform table; 10 11 // Use this for initialization 12 void Start () { 13 DbAccess db=new DbAccess("URI=file:" + Application.persistentDataPath + "/tzzm.db"); 14 int i=0; 15 using(SqliteDataReader reader=db.ReadFullTable(LevelName)) 16 { 17 while(reader.Read()) 18 { 19 i++; 20 } 21 } 22 string[] sceneNames=new string[i]; 23 for(int j=0;j<i;j++) 24 { 25 using(SqliteDataReader reader=db.SelectWhere(LevelName,new string[]{"name"},new string[]{"id"},new string[]{"="},new string[]{j.ToString()})) 26 { 27 while(reader.Read()) 28 { 29 sceneNames[j]=reader.GetString(reader.GetOrdinal("name")); 30 GameObject it = NGUITools.AddChild(table.gameObject,item); 31 it.transform.localScale=new Vector3(0.7f,0.7f,0); 32 it.transform.localPosition=new Vector3(0,0,0); 33 it.GetComponentInChildren<UILabel>().text=sceneNames[j]; 34 it.GetComponentsInChildren<UISprite>()[1].spriteName=sceneNames[j]; 35 it.GetComponentInChildren<UILabel>().depth=j; 36 it.GetComponentsInChildren<UISprite>()[1].depth=j; 37 table.GetComponent<UITable>().repositionNow=true; 38 } 39 } 40 } 41 42 } 43 44 // Update is called once per frame 45 void Update () { 46 47 } 48 }
完成脚本后赋值给摄像机,然后将item预设拖给item变量,将UITable拖给table变量。
当你完成到这里,应该就可以运行了,界面效果如下:
如果有什么疑问,可以随时给我发送邮件,我的邮箱是:[email protected]。