http://www.narkii.com/club/thread-311663-1.html
看了网上很多用GUI做的背包,小弟今天就用NGUI来实现一下简单的背包效果。先写物品进入背包和取出背包效果,下个教程实现装备穿戴,和药品使用。
首先我们来分析下游戏里面的背包功能:
1、 背包得有个背景图片吧
2、 背包得有背景格子吧
3、 背包得有最大容量吧
4、 背包里面得有物品单元吧
5、 背包总有功能吧
(1)、物品进入背包
(2)、物品从背包出去
(3)、物品从背包丢弃
(4)、物品的数量
好了,分析完功能需求以后咱们来算算需要哪些准备工作:
1、 背景图片、格子图片、物品图片这些用NGUI做个图集(这里就不多说了,一定要做个图集)
2、 掉落物品模型(这个模型自己随便找)
好了,接下来咱们就开始设计背包系统:
1、 第一步,导入NGUI这个package。导入之后菜单栏可能不会立即出现NGUI这个选项,你刷新一下Project面板等一会就会出现。接着我们来创建我们的背包面板,我们先新建一个层,名为2DUI:Layers--->edit layers --->user layer8--->输入2DUI
2、第二步,选择菜单栏NGUI--->Open--->UIWizard 我用的是NGUI 3.0.6版本不同估计这些选项的位置会有变动,但是你只要知道是创建一个新的UI就行了然后弹出窗口layer 下拉选择2DUI层,点击Create
Your UI:Hierarchy面板会出现一个UI Root(2D):


3、第三步,我们在Camera下创建一个空物体(Gameobject--->Create Empty):并命名为WindowsPanel(我们游戏里面不止一个窗口,其他的还有技能、商场、任务、装备……这个作为一个管理容器)
在windowPanel下创建一个空物体,命名为:PackageWindow,然后在PackageWindow下创建2个空物体和一个sprite,分别命名为CellBGContainer(用来放格子背景),CellContainer(用来放背包里面的物品),PackageBG(背包的背景图片):
把PackageBG的锚点设为左上角(Pivot选第一个),并把它大小(Dimensions)设为300
* 400(这个随意,大小合适就行),SpriteType设为Sliced ,depth设-1(以免将格子格子背景遮挡):然后在CellBGContainer下面创建多个sprite(个数随意)大小设为50*50 ,SpriteType设为Sliced这时sprite挤在一起:

接下来选中CellBGContainer给他添加一个Gird脚本,位置在:Component--->NGUI--->Interaction--->Gird:然后将Max
perLine设置为5(每行几个格子,这个随意,合适就行)cell width 和cell height设为50(和格子背景大小相同,也可稍微大点),然后点击Reposition
Now,这时就自动的排序了:然后选中CellBGContainer按下ctrl + D 复制一份 ;命名为CellContainer ,并删掉CellContainer所有的子Sprite :

4、第四步,我们来设计格子,在CellContainer下面新建一个按钮命名为ItemCell,将sprite命名为Icon(图标),Pivot设置为左上角,大小设置为50*50,,将label(计数用)命名为Num(数量)Pivot设置为右下角,调整位置到ItemCell的右下角(自行调整,合适就行):结构如下
然后创建5个文件夹,结构如下:分别存放我们的场景、预设、用到的图片、脚本
在Prefabs文件夹下创建一个Prefab命名为InventoryItemCell:把刚才创建的ItemCell拖上去,就有了一个InventoryItemItemCell的预设:
5、第五步,我们在PackageWindow下面创建一个空物体,命名为CellDescribe,在CellDescribe下创建一个Sprite命名为BG(Povit设为左上角,大小设为150*220合适就行,这个随意)和一个Label命名为Content(Povit设为左上角,OverFlow设为ResizeHeight,把Dimension 设为100*30这个随意,合适就行,100指label的每行长度),分别作为物品描述的背景和内容框:
然后我们在Prefabs文件夹下创建一个Prefab命名为InventoryItemCellDescribe,把CellDescribe拖上去形成一个预设:
6、第六步,我们在Scripts文件夹里面新建5个脚本:DropBase、DropObjectDataBase、DropObject、Inventory、ItemCell。功能会在下面一一说明:
DropBase它是掉落物品的类,有掉落物品的属性,DropObjectDataBase这个是掉落物品数据库,大家可以在这里面修改物品的参数,DropObject这个是掉落物品的物体,Inventory这个是背包的核心,进入背包和出背包都是通过调用这个类的方法,ItemCell这个是背包里面的元素类,负责物品的使用和属性的显示。
脚本:
DropBase.cs
-
/// <summary>
-
/// Drop base.第一个类,用来描述掉落物品的信息(id编号->可用做数据库id索引,掉落物品名,图标名称->后面要从图集里面选取图标,
-
/// Drop base.物品的描述->写个小故事,物品的值比如对自身属性的加成和红药蓝药的效果)
-
/// </summary>
-
public class DropBase {
-
public int id ;
-
public string name ;
-
public string iconname ;
-
public string describe ;
-
public float[] valuses ;
-
public int amount ;
-
/// <summary>
-
/// Initializes a new instance of the <see cref="DropBase"/> class.构造函数
-
/// </summary>
-
/// <param name="_id">_id.</param>
-
/// <param name="_name">_name.</param>
-
/// <param name="_describe">_describe.</param>
-
/// <param name="_val">_val.</param>
-
public DropBase(int _id , string _name , string _describe , float[] _val){
-
valuses = new float[5] ;
-
id = _id ;
-
name = _name ;
-
iconname = _name ;
-
describe = _describe ;
-
valuses = _val ;
-
amount = 1 ;
-
}
-
}
-
复制代码
DropObjectDataBase.cs
-
-
/// <summary>
-
/// Drop object data base.这个用来设计掉落物品的数据库,有个构造函数通过设置它的种类,来构造一个掉落物品
-
/// Drop object data base.大家可以在这里面修改属性(名称,值。etc)
-
/// </summary>
-
using UnityEngine;
-
using System.Collections;
-
using System ;
-
-
public class DropObjectDataBase : MonoBehaviour {
-
/// <summary>
-
/// DBSPCIES.这个用来设定掉落物品的大种类
-
/// </summary>
-
public enum DBSPCIES{RedBottles , BlueBottles , Equipments , Others} ;
-
/// <summary>
-
/// DBLISTS.这个用来设定掉落物品到底是什么
-
/// </summary>
-
public enum DBLISTS{
-
redPotion01 ,
-
redPotion02 ,
-
bluePotion01 ,
-
bluePotion02 ,
-
hat01 ,
-
hat02 ,
-
cloth01 ,
-
cloth02 ,
-
boot01 ,
-
boot02 ,
-
weapon01 ,
-
weapon02 ,
-
trousers01 ,
-
trousers02
-
} ;
-
public DBSPCIES dbspcies ;
-
public DBLISTS dblist ;
-
public DropBase dropBase ;
-
/// <summary>
-
/// index arr[].索引和值数组
-
/// </summary>
-
private int index ;
-
private float[] arr ;
-
-
// Use this for initialization
-
void Start () {
-
/// <summary>
-
/// switch.通过一个条件选择语句初始化DropBase,并通过名称设置它的大种类
-
/// </summary>
-
switch(dblist){
-
case DBLISTS.redPotion01:
-
index = (int)DBLISTS.redPotion01 ;
-
arr = new float[5]{ 100 , 0 , 0 , 0 , 0 } ;
-
break ;
-
case DBLISTS.redPotion02:
-
index = (int)DBLISTS.redPotion02 ;
-
arr = new float[5]{ 200 , 0 , 0 , 0 , 0 } ;
-
break ;
-
case DBLISTS.bluePotion01:
-
index = (int)DBLISTS.bluePotion01 ;
-
arr = new float[5]{ 70 , 0 , 0 , 0 , 0 } ;
-
break ;
-
case DBLISTS.bluePotion02:
-
index = (int)DBLISTS.bluePotion02 ;
-
arr = new float[5]{ 140 , 0 , 0 , 0 , 0 } ;
-
break ;
-
case DBLISTS.hat01:
-
index = (int)DBLISTS.hat01 ;
-
arr = new float[5]{ 6 , 5 , 3 , 8 , 4 } ;
-
break ;
-
case DBLISTS.hat02:
-
index = (int)DBLISTS.hat02 ;
-
arr = new float[5]{ 22 , 14 , 44 , 23 , 32 } ;
-
break ;
-
case DBLISTS.cloth01:
-
index = (int)DBLISTS.cloth01 ;
-
arr = new float[5]{ 6 , 5 , 3 , 8 , 4 } ;
-
break ;
-
case DBLISTS.cloth02:
-
index = (int)DBLISTS.cloth02 ;
-
arr = new float[5]{ 32 , 24 , 33 , 55 , 22 } ;
-
break ;
-
case DBLISTS.trousers01:
-
index = (int)DBLISTS.trousers01 ;
-
arr = new float[5]{ 6 , 5 , 3 , 8 , 4 } ;
-
break ;
-
case DBLISTS.trousers02:
-
index = (int)DBLISTS.trousers02 ;
-
arr = new float[5]{ 55 , 33 , 44 , 22 , 11 } ;
-
break ;
-
case DBLISTS.boot01:
-
index = (int)DBLISTS.boot01 ;
-
arr = new float[5]{ 6 , 5 , 3 , 8 , 4 } ;
-
break ;
-
case DBLISTS.boot02:
-
index = (int)DBLISTS.boot02 ;
-
arr = new float[5]{ 31 , 22 , 41 , 31 , 27 } ;
-
break ;
-
case DBLISTS.weapon01:
-
index = (int)DBLISTS.weapon01 ;
-
arr = new float[5]{ 65 , 12 , 33 , 65 , 12 } ;
-
break ;
-
case DBLISTS.weapon02:
-
index = (int)DBLISTS.weapon02 ;
-
arr = new float[5]{ 223 , 112 , 445 , 263 , 112 } ;
-
break ;
-
}
-
/// <summary>
-
/// new DropBase.构造一个物品
-
/// </summary>
-
dropBase = new DropBase( index , ((DBLISTS)Enum.ToObject(typeof(DBLISTS),index )).ToString() , "" , arr);
-
/// <summary>
-
/// if-else.设定它的大种类
-
/// </summary>
-
if(dblist <= DBLISTS.redPotion02 && dblist >= DBLISTS.redPotion01){
-
dbspcies = DBSPCIES.RedBottles ;
-
}else if(dblist <= DBLISTS.bluePotion02 && dblist >= DBLISTS.bluePotion01){
-
dbspcies = DBSPCIES.BlueBottles ;
-
}else if(dblist <= DBLISTS.weapon02 && dblist >= DBLISTS.hat01){
-
dbspcies = DBSPCIES.Equipments ;
-
}
-
//print(dblist +""+ dbspcies);
-
}
-
}
复制代码
Inventory.cs
-
-
/// <summary>
-
/// Inventory.背包的核心类,背包操作
-
/// </summary>
-
using UnityEngine;
-
using System.Collections;
-
/// <summary>
-
/// Inventory.要使用List线性表,需要引入这个Generic
-
/// </summary>
-
using System.Collections.Generic ;
-
-
public class Inventory : MonoBehaviour {
-
/// <summary>
-
/// The inventory list.定义一个存放gameobject的线性表
-
/// </summary>
-
private List<GameObject> inventoryList ;
-
// Use this for initialization
-
void Start () {
-
inventoryList = new List<GameObject>() ;
-
}
-
-
/// <summary>
-
/// Adds the item.物品进入背包函数,接受一个gameobject参数
-
/// </summary>
-
/// <param name="_goadd">_goadd.</param>
-
public void AddItem(GameObject _goadd){
-
/// <summary>
-
/// if-else.先通过CheckExisted函数判断背包里面是否存在这个物品如果有就把传过来的gameobject销毁在CheckExisted函数里面将数量加1
-
/// </summary>
-
if(CheckExisted(_goadd)){
-
Destroy(_goadd) ;
-
}else{
-
/// <summary>
-
/// if-else.背包里面如果存在这个物品,就把传过来的gameobject添加到线性表里去,并且把传过来的gameobject设定为背包的子物体
-
/// </summary>
-
inventoryList.Add(_goadd);
-
_goadd.transform.parent = gameObject.transform ;
-
/// <summary>
-
/// localScale.设定它的缩放,不然它会很巨大
-
/// </summary>
-
_goadd.transform.localScale = new Vector3(1,1,1);
-
}
-
-
ReFreshInventory();
-
}
-
/// <summary>
-
/// Removes the item.将物品从背包删除,先从线性表里删除,然后再更新背包界面,最后销毁物体
-
/// </summary>
-
/// <param name="_goremove">_goremove.</param>
-
public void RemoveItem(GameObject _goremove){
-
inventoryList.Remove(_goremove);
-
ReFreshInventory();
-
Destroy(_goremove);
-
}
-
/// <summary>
-
/// Res the fresh inventory.更新背包界面,从线性表读取物品信息并刷新界面
-
/// </summary>
-
public void ReFreshInventory(){
-
foreach(GameObject g in inventoryList){
-
g.GetComponentInChildren<UILabel>().text = g.GetComponent<DropObjectDataBase>().dropBase.amount + "" ;
-
}
-
/// <summary>
-
/// Reposition.重新调整背包物品排列,UIGird的函数
-
/// </summary>
-
gameObject.GetComponent<UIGrid>().Reposition() ;
-
}
-
/// <summary>
-
/// Checks the existed.检测背包物品list里面的物体是否存在,通过比较物品名称种类实现判断,如果有就将数量加1,函数返回一个bool值
-
/// </summary>
-
/// <returns><c>true</c>, if existed was checked, <c>false</c> otherwise.</returns>
-
/// <param name="_go">_go.</param>
-
bool CheckExisted(GameObject _go){
-
bool flag = false ;
-
foreach(GameObject _obje in inventoryList){
-
if(_go.GetComponent<DropObjectDataBase>().dblist == _obje.GetComponent<DropObjectDataBase>().dblist){
-
_obje.GetComponent<DropObjectDataBase>().dropBase.amount ++ ;
-
flag = true ;
-
break ;
-
}else{
-
flag = false ;
-
}
-
}
-
return flag ;
-
}
-
}
-
复制代码
ItemCell.cs
-
-
/// <summary>
-
/// Item cell.
-
/// </summary>
-
using UnityEngine;
-
using System.Collections;
-
-
[RequireComponent(typeof(DropObjectDataBase))]
-
public class ItemCell : MonoBehaviour {
-
/// <summary>
-
/// The cell DES.这个用来显示背包格子里面的信息,比如装备的属性之类的
-
/// </summary>
-
private GameObject cellDes ;
-
/// <summary>
-
/// The _cell D.这个用来获取格子身上的数据库脚本。因为需要用到里面的数值
-
/// </summary>
-
private DropObjectDataBase _cellDB ;
-
// Use this for initialization
-
void Start () {
-
_cellDB = gameObject.GetComponent<DropObjectDataBase>() ;
-
cellDes = GameObject.Find("InventoryItemCellDescribe");
-
/// <summary>
-
/// cellDes.transform.position.这句话用来设置属性描述框的初始位置,就是放到看不到的位置
-
/// </summary>
-
cellDes.transform.position = new Vector3(0,10000,0);
-
}
-
/// <summary>
-
/// Raises the click event.当鼠标点击物品的时候先判断物品的数量是否大于1个,如果大于1个的话就数量上减去1,否则刚好有一个的话就把它从背包删除
-
/// </summary>
-
void OnClick(){
-
if(gameObject.GetComponent<DropObjectDataBase>().dropBase.amount > 1){
-
gameObject.GetComponent<DropObjectDataBase>().dropBase.amount -- ;
-
}else{
-
this.transform.parent.GetComponent<Inventory>().RemoveItem(this.gameObject);
-
/// <summary>
-
/// DesHide.删除物品的同时将物品介绍面板隐藏
-
/// </summary>
-
DesHide();
-
}
-
this.transform.parent.GetComponent<Inventory>().ReFreshInventory();
-
}
-
/// <summary>
-
/// Raises the hover event.鼠标悬浮在物品上面的时候调用,接受一个参数,
-
/// </summary>
-
/// <param name="isOver">If set to <c>true</c> is over.</param>
-
void OnHover(bool isOver){
-
if(isOver){
-
DesShow();
-
}else{
-
DesHide();
-
}
-
}
-
/// <summary>
-
/// DESs the show.将属性显示面板的位置设置到物品的位置,并设置属性面板内容,从数据库脚本中读取
-
/// </summary>
-
void DesShow(){
-
cellDes.transform.position = gameObject.transform.position ;
-
cellDes.GetComponentInChildren<UILabel>().text = _cellDB.dropBase.name + "\n" +
-
_cellDB.dropBase.describe + "\n" +
-
_cellDB.dropBase.valuses[0] ;
-
}
-
/// <summary>
-
/// DESs the hide.将面板的y值设置到一个看不到的敌方,来实现面板隐藏
-
/// </summary>
-
void DesHide(){
-
cellDes.transform.position = new Vector3(0,10000,0);
-
}
-
-
void OnPress(){
-
-
}
-
}
复制代码
DropObject.cs
-
-
/// <summary>
-
/// Drop object.怪物死亡后会掉落物品
-
/// </summary>
-
using UnityEngine;
-
using System.Collections;
-
-
[RequireComponent(typeof(DropObjectDataBase))]
-
public class DropObject : MonoBehaviour {
-
/// <summary>
-
/// Prefab.通过预设生成一个背包里面的格子
-
/// </summary>
-
public GameObject itemCellPrefab ;
-
/// <summary>
-
/// Cellcontainer.背包格子父容器
-
/// </summary>
-
private GameObject Cellcontainer ;
-
// Use this for initialization
-
void Start () {
-
Cellcontainer = GameObject.Find("CellContainer");
-
}
-
/// <summary>
-
/// Raises the mouse down event.这里设定的是鼠标点选,大家可以设置trigger触发器触发拣选
-
/// </summary>
-
void OnMouseDown(){
-
CellCreation();
-
}
-
/// <summary>
-
/// Cells the creation.通过Instantiate克隆出一个格子预设,调用背包脚本的AddItem函数将这个clone出来的物体加到背包里面去
-
/// Cells the creation.把掉落的物品的三个属性传给clone出来的物品,并设定它的图集图标
-
/// </summary>
-
void CellCreation(){
-
GameObject cellClone = (GameObject)Instantiate(itemCellPrefab);
-
cellClone.GetComponent<DropObjectDataBase>().dblist = gameObject.GetComponent<DropObjectDataBase>().dblist ;
-
cellClone.GetComponent<DropObjectDataBase>().dropBase = gameObject.GetComponent<DropObjectDataBase>().dropBase ;
-
cellClone.GetComponent<DropObjectDataBase>().dbspcies = gameObject.GetComponent<DropObjectDataBase>().dbspcies ;
-
cellClone.GetComponentInChildren<UISprite>().spriteName = cellClone.GetComponent<DropObjectDataBase>().dropBase.iconname ;
-
if(Cellcontainer){
-
Cellcontainer.GetComponent<Inventory>().AddItem(cellClone);
-
}else{
-
print ("Failed to Instantiate.......");
-
}
-
}
-
}
-
复制代码
然后在创建一个cube当作掉落物品模型,这个大家可以随便替换模型。
脚本关系:
Cube上拖一个Dropobject,InventoryItemCell上拖一个ItemCell脚本;