• QQ
  • nahooten@sina.com
  • 常州市九洲新世界花苑15-2

游戏开发

常州网游开发-NGUI简单背包系统的实现

原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/youxikaifa/2018/1224/263.html

常州网站开发建设-NGUI简单背包系统的实现

  一、利用txt文件存储游戏物品信息

  首先在asset下创建一个txt文件,这里我们命名为objectsInfoList.txt,并将其拖放到unity Project视图中。

  其中txt中我们先存放一些物品信息,每行存储一种物品信息,分别为编号、名称、物品对应的图片名、种类、回血值、回蓝值、出售价和购买价。

  其中物品图片要先用NGUI做成图集,种类中的Drug为药品类,以后在代码中我们会定义一个枚举用于存储物品种类。

  接下来我们常州微信小程序开发-幻天网络创建一个空物体叫做GameSetting,上面挂一个脚本ObjectsInfo,我们把txt文件读取到一个string中,根据'\n'及','分割字符串,取得对应的物品信息,然后存储到Dictionary中,以后需要物品信息时便可以从dictionary中取出来了。

  代码如下,就不做具体解释了。。。虽然注释少点,但还是挺简单的
 

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
public class ObjectsInfo : MonoBehaviour 
{
 
    public static ObjectsInfo _instance;
    public TextAsset objectsInfoListText;
 
    private Dictionary<int, ObjectInfo> objectInfoDictionary =
        new Dictionary<int, ObjectInfo>();
 
    void Awake()
    {
        _instance = this;
        ReadInfo();
    }
 
    public ObjectInfo GetObjectInfoById(int key)
    {
        ObjectInfo info = new ObjectInfo();
        objectInfoDictionary.TryGetValue(key, out info);
        return info;
    }
    private void ReadInfo()
    {
        string text = objectsInfoListText.text;
        string[] strArray = text.Split('\n');
        foreach (string str in strArray)
        {
            string[] proArray = str.Split(',');
 
            ObjectInfo info = new ObjectInfo();
 
            int id = int.Parse(proArray[0]);
            string name = proArray[1];
            string iconName = proArray[2];
            string typeStr = proArray[3];
 
            info.id=id;
            info.name=name;
            info.iconName=iconName;
            ObjectType type = ObjectType.Drug;
            switch (typeStr)
            { 
                case "Drug":
                    type = ObjectType.Drug;
                    break;
                case "Equip":
                    type = ObjectType.Equip;
                    break;
                case "Mat":
                    type = ObjectType.Mat;
                    break;
            }
            info.type=type;
            if (type == ObjectType.Drug)
            {
                int hp = int.Parse(proArray[4]);
                int mp = int.Parse(proArray[5]);
                int priceSell = int.Parse(proArray[6]);
                int priceBuy = int.Parse(proArray[7]);
 
                info.hp = hp;
                info.mp = mp;
                info.priceBuy = priceBuy;
                info.priceSell = priceSell;
            }
 
            //添加到字典上,id为key,方便根据id查找
            objectInfoDictionary.Add(id, info);
        }
    }
}
 
public enum ObjectType 
{
    Drug,
    Equip,
    Mat
}
 
//id,名称,icon名称,类型,加血值,加蓝值,卖出价,买入价
public class ObjectInfo
{
    public int id;
    public string name;
    public string iconName;
    public ObjectType type;
    public int hp;
    public int mp;
    public int priceSell;
    public int priceBuy;
}

 

  二、背包系统

  1、设计背包系统的UI界面

  主界面背景:新建一个sprite,选择常州网站开发建设相应图片,命名为Inventory

  格子:在Inventory下创建sprite,并在下面创建一个label用来显示物品数量,命名为NumLabel,然后做成prefab并复制多个

  其他:整理背包按钮、金钱图标及显示金币数量的label

 

  做出来的界面如下


 

2、控制背包物品的管理

   我们给Inventory添加一个脚本命名为Inventory,给格子添加一个脚本命名为InventoryItemGrid方便对格子的管理

 

   在Inventory脚本中,定义一个List<InventoryItemGrid> itemGridList用于存放背包的所有格子,并在我们游戏开发运营unity界面中将所有格子拖过去赋值(注意要按照格子的顺序赋值,所以格子创建完后,最好给格子分别命名一下如gide00,grid01.....,也方便以后的测试),并定义好金钱数目等变量;我们给背包添加一个tween动画,控制背包的显示与隐藏,并在脚本中提供相应方法,具体代码如下
 

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
public class Inventory : MonoBehaviour {
 
    public static Inventory _instance;
    private TweenPosition tweenPosition;
 
    private int coinCount = 1000;
    public UILabel coinCountLabel;
 
    public List<InventoryItemGrid> itemGridList = new List<InventoryItemGrid>();
 
    // Use this for initialization
    void Awake () {
        _instance = this;
        tweenPosition = GetComponent<TweenPosition>();
    }
    
    private bool isShow = false;
    private void Show()
    {
        isShow = true;
        tweenPosition.PlayForward();
    }
 
    private void Hide()
    {
        isShow = false;
        tweenPosition.PlayReverse();
    }
   
 
    public void TransformState()
    {
        if (!isShow)
        {
            Show();
            isShow = true;
        }
        else
        {
            Hide();
            isShow = false;
        }
    }

 

}

3、背包方格物品的prefab制作

  在格子下创建一个sprite,可以随便选一张图片,调整大小使之适应格子大小,将其做成prefab,添加一个脚本命名为InventoryItem 

  由于我们的物品应该是可以拖动的,所以常州游戏开发培训应attach一个Box Collider,脚本InventoryItem让其继承于UIDragDropItem 便可以实现拖拽功能了。定义一个int id用于设置要显示物品的id,并提供一个SetId方法控制对应图片的显示。代码如下: 

using UnityEngine;
using System.Collections;
 
public class InventoryItem : UIDragDropItem {
 
    private UISprite sprite;
    private int id;
 
    void Awake()
    {
        base.Awake();
        sprite = this.gameObject.GetComponent<UISprite>();
    }
 
    public void SetId(int id)
    {
        ObjectInfo info = ObjectsInfo._instance.GetObjectInfoById(id);
        sprite.spriteName = info.iconName;
        this.id = id;
    }
 
   
}

 4、控制方格对下面物品的管理

   InventoryItemGrid脚本中定义变量id为物品的编号,num为物品的数量,以及UILabel控制物品数量的显示,手机App外包并获取格子下面物品上的脚本InventoryItem调用上面的SetId方法,设置物品相应的图片。代码很简单。。。

using UnityEngine;
using System.Collections;
 
public class InventoryItemGrid : MonoBehaviour {
 
    public int id = 0;
    public int num = 0;
    private ObjectInfo info = null;
    private UILabel numLabel;
 
    void Start()
    {
        numLabel = this.GetComponentInChildren<UILabel>();
    }
 
    public void SetId(int id, int num = 1)
    {
        this.id = id;
        info = ObjectsInfo._instance.GetObjectInfoById(id);
        InventoryItem item = this.GetComponentInChildren<InventoryItem>();       
        this.num = num;
        numLabel.text = this.num.ToString();
        numLabel.enabled = true;
 
        item.SetId(id);
    }
 
    public void PlusNum(int num = 1)
    {
        this.num += num;
        numLabel.text = this.num.ToString();
    }
    public void ClearInfo()
    {
        id = 0;
        num = 0;
        info = null;
        numLabel.enabled = false;
    }
}

5、背包物品的拾取功能

   由于我们txt文件中只存储了3种物品,这里我们使用随机数模拟一下拾取功能,每次按下x键随机一个数,并根据App开发培训id取得该物品其他信息,实例化该物体并调整坐标及parent

void Update () {
        if (Input.GetKeyDown(KeyCode.X))
        {
            GetSomething(Random.Range(1001, 1004));
        }
    }
 
    private void GetSomething(int id)
    {
        InventoryItemGrid grid = null;
        //检测grid中有没有当前物体
        foreach (InventoryItemGrid temp in itemGridList)
        {
            if (temp.id == id)
            {
                grid = temp;
                break;
            }
        }
        if (grid != null)//有当前物体 num加1
        {
            grid.PlusNum(1);
        }
        else//没有当前物体 查找是否有空格 根据id是否为0判断
        {
            foreach (InventoryItemGrid temp in itemGridList)
            {
                if (temp.id == 0)
                {
                    grid = temp;
                    break;
                }
            }
 
            if (grid != null)//有空格
            {
                //在当前格实例化物体
                GameObject go = NGUITools.AddChild(grid.gameObject, inventoryItemGameobject);
                go.transform.localPosition = Vector3.zero;
                go.GetComponent<UISprite>().depth = 8;
                grid.SetId(id);
 
            }
            else//没有空格
            {
                print("背包满了");  
            }
 
        }
    }

6、实现背包物品的拖拽功能

  物品的拖拽有几种情况需要分别实现:物品拖到一个空格,物品拖到有物品的格子、两物品应交换位置信息,物品拖到背包界面外等应还在当前格子

  拖拽功能的实现应在protected override void OnDragDropRelease(GameObject surface) 这个函数中实现,判断常州网站开发培训拖放结束时停留的物体为surface,要区分surface的类别,应根据tag来实现,因此我们给所有的格子添加Tag InventoryItemGrid,给物品添加Tag InventoryItem,为了方便tag管理我们添加一个Tags脚本,其中存储各种企业培训Tags信息  
 

using UnityEngine;
using System.Collections;
 
public class Tags : MonoBehaviour {
 
    public const string GROUND = "Ground";
    public const string PLAYER = "Player";
    public const string INVENTORY_ITEM = "InventoryItem";
    public const string INVENTORY_ITEM_GRID = "InventoryItemGrid";
}


物品拖拽功能的实现代码如下


protected override void OnDragDropRelease(GameObject surface)
    {
        base.OnDragDropRelease(surface);
 
        if (surface != null)
        {
            //拖放到一个有物体的格子
            if (surface.tag == Tags.INVENTORY_ITEM)
            {
                InventoryItemGrid oldGrid = this.transform.parent.GetComponent<InventoryItemGrid>();
                int id = oldGrid.id;
                int num = oldGrid.num;
                InventoryItemGrid newGrid = surface.transform.parent.GetComponent<InventoryItemGrid>();
 
                //交换数据
                oldGrid.SetId(newGrid.id, newGrid.num);
                newGrid.SetId(id, num);
 
                ResetPosition();
            }
            //拖放到一个空格子
            else if (surface.tag == Tags.INVENTORY_ITEM_GRID)
            {
                //拖放到自己的格子
                if (surface.transform.parent == this.transform.parent)
                {
                    ResetPosition();
                }
                else//其他空格子 
                {
                    InventoryItemGrid oldGrid = this.transform.parent.GetComponent<InventoryItemGrid>();
 
                    InventoryItemGrid nowGrid = surface.GetComponent<InventoryItemGrid>();
                    this.transform.parent = surface.transform;
                    ResetPosition();
                    nowGrid.SetId(oldGrid.id, oldGrid.num);
                    oldGrid.ClearInfo();
                }
 
            }
            else
            {
                ResetPosition();
            }
        }
        else
        {
            ResetPosition();
        }
    }
 
    private void ResetPosition()
    {
        transform.localPosition = Vector3.zero;
    }

 

7、背包物品的信息提示

   在unity背包下面添加一个sprite作为提示信息的背景,背景下面添加一个label显示提示信息。

  我们应在鼠标放在物品上时显示该物品的详细信息,鼠标移出时提示信息框则应消失。要常州软件技术培训实现这种效果,我们可以在物品prefab上添加一个NGUI提供的UI Event Trigger组件,On Hover Over和On Hover Out分别绑定InventoryItem中的两个函数
 

public void OnHoverOver()
    {
        InventoryDes._instance.Show(id,this.transform.position);
    }
 
    public void OnHoverOut()
    {
        InventoryDes._instance.Hide();
    }

 在界面上提示信息的sprite上面挂一个脚本命名为InventoryDes,常州平台运营该脚本控制提示信息的显示隐藏等功能



using UnityEngine;
using System.Collections;
 
public class InventoryDes : MonoBehaviour {
 
    public static InventoryDes _instance;
 
    private UILabel label;
    void Awake()
    {
        _instance = this;
        label = this.GetComponentInChildren<UILabel>();
        this.gameObject.SetActive(false);
    }
 
    public void Show(int id,Vector3 pos)
    {
        this.gameObject.SetActive(true);
        this.transform.position = pos;
        ObjectInfo info = ObjectsInfo._instance.GetObjectInfoById(id);
        string des = "";
        switch (info.type)
        { 
            case ObjectType.Drug:
                des = GetDrugDes(info);
                break;
            case ObjectType.Equip:
                break;
            case ObjectType.Mat:
                break;
        }
        label.text = des;
    }
 
    public void Hide()
    {
        this.gameObject.SetActive(false);
    }
    private string GetDrugDes(ObjectInfo info)
    {
        string s = "";
        s += "名称:" + info.name + "\n";
        s += "回复Hp:" + info.hp + "\n";
        s += "回复Mp:" + info.mp + "\n";
        s += "出售价:" + info.priceSell + "\n";
        s += "购买价:" + info.priceBuy + "\n";
        return s;
    }
}


 8、背包物品的整理功能

   当我们背包中的物品排列很散乱是,点击整理按钮,所有的物品应有序的从前到后排列整齐,中间应该没有空格,这个功能该如何实现呢?这里提供一种方法,可能效率不是最高的(没有想到更好的实现方法,有常州微信公众平台更好方法的朋友请告诉我们幻天网络),但可以实现基本要求:

 

例如上面的图,有红圈的地方代表有物体,其余为空格,我们怎样将物品排列好使之没有空格呢?我们可以先将所有格子遍历一变,记下空格的索引;然后从最小的索引

开始向后循环,将所有格子从后向前遍历,如果格子中有物体则将其移动到该空格索引对应的格子中,然后常州微信小程序开发继续...  

  下面是代码:

//整理背包物品
    public void OnArrangeInventory()
    {
        List<int> nullGridIndexList = new List<int>();
        for (int i = 0; i < itemGridList.Count; i++)
        {
            if (itemGridList[i].id == 0)
            {
                nullGridIndexList.Add(i);
            }
        }
        //背包满了不整理
        if (nullGridIndexList.Count != 0)
        {
            
            foreach (int index in nullGridIndexList)
            {
 
                for (int i = itemGridList.Count - 1; i > index; i--)
                {
                    if (itemGridList[i].id != 0)
                    {
                        if (i > index)
                        {
                            ExchangeItemToANullGrid(index, i);
                            break;
                        }
                        else
                            break;
                    }
                }
            }
        }
    }
 
    //index为空格子索引, i为有物品的格子
    private void ExchangeItemToANullGrid(int index, int i)
    {
 
        Transform transform = itemGridList[i].GetComponentInChildren<InventoryItem>().gameObject.transform;
        transform.parent
            = itemGridList[index].transform;
        transform.localPosition = Vector3.zero;
        itemGridList[index].SetId(itemGridList[i].id, itemGridList[i].num);
        itemGridList[i].ClearInfo();

 

    }

至此,常州网站开发建设一个简单但功能齐全的背包系统便做好了!


上篇:上一篇:常州手游开发-Unity3D中常用的数据结构
下篇:下一篇:unity3d简单的相机跟随及视野旋转缩放