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

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

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

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

  

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

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

  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. public class ObjectsInfo : MonoBehaviour
  6. {
  7.  
  8. public static ObjectsInfo _instance;
  9. public TextAsset objectsInfoListText;
  10.  
  11. private Dictionary<int, ObjectInfo> objectInfoDictionary =
  12. new Dictionary<int, ObjectInfo>();
  13.  
  14. void Awake()
  15. {
  16. _instance = this;
  17. ReadInfo();
  18. }
  19.  
  20. public ObjectInfo GetObjectInfoById(int key)
  21. {
  22. ObjectInfo info = new ObjectInfo();
  23. objectInfoDictionary.TryGetValue(key, out info);
  24. return info;
  25. }
  26. private void ReadInfo()
  27. {
  28. string text = objectsInfoListText.text;
  29. string[] strArray = text.Split('\n');
  30. foreach (string str in strArray)
  31. {
  32. string[] proArray = str.Split(',');
  33.  
  34. ObjectInfo info = new ObjectInfo();
  35.  
  36. int id = int.Parse(proArray[]);
  37. string name = proArray[];
  38. string iconName = proArray[];
  39. string typeStr = proArray[];
  40.  
  41. info.id=id;
  42. info.name=name;
  43. info.iconName=iconName;
  44. ObjectType type = ObjectType.Drug;
  45. switch (typeStr)
  46. {
  47. case "Drug":
  48. type = ObjectType.Drug;
  49. break;
  50. case "Equip":
  51. type = ObjectType.Equip;
  52. break;
  53. case "Mat":
  54. type = ObjectType.Mat;
  55. break;
  56. }
  57. info.type=type;
  58. if (type == ObjectType.Drug)
  59. {
  60. int hp = int.Parse(proArray[]);
  61. int mp = int.Parse(proArray[]);
  62. int priceSell = int.Parse(proArray[]);
  63. int priceBuy = int.Parse(proArray[]);
  64.  
  65. info.hp = hp;
  66. info.mp = mp;
  67. info.priceBuy = priceBuy;
  68. info.priceSell = priceSell;
  69. }
  70.  
  71. //添加到字典上,id为key,方便根据id查找
  72. objectInfoDictionary.Add(id, info);
  73. }
  74. }
  75. }
  76.  
  77. public enum ObjectType
  78. {
  79. Drug,
  80. Equip,
  81. Mat
  82. }
  83.  
  84. //id,名称,icon名称,类型,加血值,加蓝值,卖出价,买入价
  85. public class ObjectInfo
  86. {
  87. public int id;
  88. public string name;
  89. public string iconName;
  90. public ObjectType type;
  91. public int hp;
  92. public int mp;
  93. public int priceSell;
  94. public int priceBuy;
  95. }

  二、背包系统

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

  主界面背景:新建一个sprite,选择相应图片,命名为Inventory

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

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

  做出来的界面如下

  

  2、控制背包物品的管理

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

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

  

  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. public class Inventory : MonoBehaviour {
  6.  
  7. public static Inventory _instance;
  8. private TweenPosition tweenPosition;
  9.  
  10. private int coinCount = ;
  11. public UILabel coinCountLabel;
  12.  
  13. public List<InventoryItemGrid> itemGridList = new List<InventoryItemGrid>();
  14.  
  15. // Use this for initialization
  16. void Awake () {
  17. _instance = this;
  18. tweenPosition = GetComponent<TweenPosition>();
  19. }
  20.  
  21. private bool isShow = false;
  22. private void Show()
  23. {
  24. isShow = true;
  25. tweenPosition.PlayForward();
  26. }
  27.  
  28. private void Hide()
  29. {
  30. isShow = false;
  31. tweenPosition.PlayReverse();
  32. }
  33.  
  34. public void TransformState()
  35. {
  36. if (!isShow)
  37. {
  38. Show();
  39. isShow = true;
  40. }
  41. else
  42. {
  43. Hide();
  44. isShow = false;
  45. }
  46. }
  47. }

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

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

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

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class InventoryItem : UIDragDropItem {
  5.  
  6. private UISprite sprite;
  7. private int id;
  8.  
  9. void Awake()
  10. {
  11. base.Awake();
  12. sprite = this.gameObject.GetComponent<UISprite>();
  13. }
  14.  
  15. public void SetId(int id)
  16. {
  17. ObjectInfo info = ObjectsInfo._instance.GetObjectInfoById(id);
  18. sprite.spriteName = info.iconName;
  19. this.id = id;
  20. }
  21.  
  22. }

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

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

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class InventoryItemGrid : MonoBehaviour {
  5.  
  6. public int id = ;
  7. public int num = ;
  8. private ObjectInfo info = null;
  9. private UILabel numLabel;
  10.  
  11. void Start()
  12. {
  13. numLabel = this.GetComponentInChildren<UILabel>();
  14. }
  15.  
  16. public void SetId(int id, int num = )
  17. {
  18. this.id = id;
  19. info = ObjectsInfo._instance.GetObjectInfoById(id);
  20. InventoryItem item = this.GetComponentInChildren<InventoryItem>();
  21. this.num = num;
  22. numLabel.text = this.num.ToString();
  23. numLabel.enabled = true;
  24.  
  25. item.SetId(id);
  26. }
  27.  
  28. public void PlusNum(int num = )
  29. {
  30. this.num += num;
  31. numLabel.text = this.num.ToString();
  32. }
  33. public void ClearInfo()
  34. {
  35. id = ;
  36. num = ;
  37. info = null;
  38. numLabel.enabled = false;
  39. }
  40. }

  5、背包物品的拾取功能

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

  1. void Update () {
  2. if (Input.GetKeyDown(KeyCode.X))
  3. {
  4. GetSomething(Random.Range(, ));
  5. }
  6. }
  7.  
  8. private void GetSomething(int id)
  9. {
  10. InventoryItemGrid grid = null;
  11. //检测grid中有没有当前物体
  12. foreach (InventoryItemGrid temp in itemGridList)
  13. {
  14. if (temp.id == id)
  15. {
  16. grid = temp;
  17. break;
  18. }
  19. }
  20. if (grid != null)//有当前物体 num加1
  21. {
  22. grid.PlusNum();
  23. }
  24. else//没有当前物体 查找是否有空格 根据id是否为0判断
  25. {
  26. foreach (InventoryItemGrid temp in itemGridList)
  27. {
  28. if (temp.id == )
  29. {
  30. grid = temp;
  31. break;
  32. }
  33. }
  34.  
  35. if (grid != null)//有空格
  36. {
  37. //在当前格实例化物体
  38. GameObject go = NGUITools.AddChild(grid.gameObject, inventoryItemGameobject);
  39. go.transform.localPosition = Vector3.zero;
  40. go.GetComponent<UISprite>().depth = ;
  41. grid.SetId(id);
  42.  
  43. }
  44. else//没有空格
  45. {
  46. print("背包满了");
  47. }
  48.  
  49. }
  50. }

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

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

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

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class Tags : MonoBehaviour {
  5.  
  6. public const string GROUND = "Ground";
  7. public const string PLAYER = "Player";
  8. public const string INVENTORY_ITEM = "InventoryItem";
  9. public const string INVENTORY_ITEM_GRID = "InventoryItemGrid";
  10. }

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

  1. protected override void OnDragDropRelease(GameObject surface)
  2. {
  3. base.OnDragDropRelease(surface);
  4.  
  5. if (surface != null)
  6. {
  7. //拖放到一个有物体的格子
  8. if (surface.tag == Tags.INVENTORY_ITEM)
  9. {
  10. InventoryItemGrid oldGrid = this.transform.parent.GetComponent<InventoryItemGrid>();
  11. int id = oldGrid.id;
  12. int num = oldGrid.num;
  13. InventoryItemGrid newGrid = surface.transform.parent.GetComponent<InventoryItemGrid>();
  14.  
  15. //交换数据
  16. oldGrid.SetId(newGrid.id, newGrid.num);
  17. newGrid.SetId(id, num);
  18.  
  19. ResetPosition();
  20. }
  21. //拖放到一个空格子
  22. else if (surface.tag == Tags.INVENTORY_ITEM_GRID)
  23. {
  24. //拖放到自己的格子
  25. if (surface.transform.parent == this.transform.parent)
  26. {
  27. ResetPosition();
  28. }
  29. else//其他空格子
  30. {
  31. InventoryItemGrid oldGrid = this.transform.parent.GetComponent<InventoryItemGrid>();
  32.  
  33. InventoryItemGrid nowGrid = surface.GetComponent<InventoryItemGrid>();
  34. this.transform.parent = surface.transform;
  35. ResetPosition();
  36. nowGrid.SetId(oldGrid.id, oldGrid.num);
  37. oldGrid.ClearInfo();
  38. }
  39.  
  40. }
  41. else
  42. {
  43. ResetPosition();
  44. }
  45. }
  46. else
  47. {
  48. ResetPosition();
  49. }
  50. }
  51.  
  52. private void ResetPosition()
  53. {
  54. transform.localPosition = Vector3.zero;
  55. }

  7、背包物品的信息提示

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

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

  1. public void OnHoverOver()
  2. {
  3. InventoryDes._instance.Show(id,this.transform.position);
  4. }
  5.  
  6. public void OnHoverOut()
  7. {
  8. InventoryDes._instance.Hide();
  9. }

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

  

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class InventoryDes : MonoBehaviour {
  5.  
  6. public static InventoryDes _instance;
  7.  
  8. private UILabel label;
  9. void Awake()
  10. {
  11. _instance = this;
  12. label = this.GetComponentInChildren<UILabel>();
  13. this.gameObject.SetActive(false);
  14. }
  15.  
  16. public void Show(int id,Vector3 pos)
  17. {
  18. this.gameObject.SetActive(true);
  19. this.transform.position = pos;
  20. ObjectInfo info = ObjectsInfo._instance.GetObjectInfoById(id);
  21. string des = "";
  22. switch (info.type)
  23. {
  24. case ObjectType.Drug:
  25. des = GetDrugDes(info);
  26. break;
  27. case ObjectType.Equip:
  28. break;
  29. case ObjectType.Mat:
  30. break;
  31. }
  32. label.text = des;
  33. }
  34.  
  35. public void Hide()
  36. {
  37. this.gameObject.SetActive(false);
  38. }
  39. private string GetDrugDes(ObjectInfo info)
  40. {
  41. string s = "";
  42. s += "名称:" + info.name + "\n";
  43. s += "回复Hp:" + info.hp + "\n";
  44. s += "回复Mp:" + info.mp + "\n";
  45. s += "出售价:" + info.priceSell + "\n";
  46. s += "购买价:" + info.priceBuy + "\n";
  47. return s;
  48. }
  49. }

  8、背包物品的整理功能

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

  

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

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

  下面是代码:

  

  1. //整理背包物品
  2. public void OnArrangeInventory()
  3. {
  4. List<int> nullGridIndexList = new List<int>();
  5. for (int i = ; i < itemGridList.Count; i++)
  6. {
  7. if (itemGridList[i].id == )
  8. {
  9. nullGridIndexList.Add(i);
  10. }
  11. }
  12. //背包满了不整理
  13. if (nullGridIndexList.Count != )
  14. {
  15.  
  16. foreach (int index in nullGridIndexList)
  17. {
  18.  
  19. for (int i = itemGridList.Count - ; i > index; i--)
  20. {
  21. if (itemGridList[i].id != )
  22. {
  23. if (i > index)
  24. {
  25. ExchangeItemToANullGrid(index, i);
  26. break;
  27. }
  28. else
  29. break;
  30. }
  31. }
  32. }
  33. }
  34. }
  35.  
  36. //index为空格子索引, i为有物品的格子
  37. private void ExchangeItemToANullGrid(int index, int i)
  38. {
  39.  
  40. Transform transform = itemGridList[i].GetComponentInChildren<InventoryItem>().gameObject.transform;
  41. transform.parent
  42. = itemGridList[index].transform;
  43. transform.localPosition = Vector3.zero;
  44. itemGridList[index].SetId(itemGridList[i].id, itemGridList[i].num);
  45. itemGridList[i].ClearInfo();
  46. }

  至此,一个简单但功能齐全的背包系统便做好了! 

NGUI简单背包系统的实现的更多相关文章

  1. NGUI 简单的背包系统

    1.首先在场景中创建格子,用来存放物体的 2.为每一个格子设置标签为Item,建议只做一个格子,然后创建预制体就可以了,然后为每一个格子附加Box Collider组件,要用于检测嘛, 3.接下来就是 ...

  2. NGU-学习笔记(1)-动态添加删除图集

    现在 正在做unity的方向 不得不说我选的是UI方向 Unity中很有名的就是NGUI插件了.今天做了个ngui的简单背包系统.非常简陋..初学着 自己mark下 (1)预览 主要就是个 simpl ...

  3. Unity开发心路历程——制作画板

    有人说 编程是份很无聊的工作 因为整个工作时间面对的都是电脑这种机器 因为眼睛盯着的内容都是索然无味的代码 因为总是会有意想不到的bug让你怀疑自己的智商 而我认为 编程是件及其有意思的事情 可观的收 ...

  4. Unity3D使用NGUI实现简单背包功能

    前话 在许多类型游戏中我们经常会使用到背包,利用背包来设置相应角色属性,多了背包也会让游戏增色拓展不少. 那在Unity3D游戏开发中该如何编写背包系统呢?因为有高人开发了NGUI插件,因此我们进行简 ...

  5. NGUI之Slider,最简单的方法做进度条。

    既然标题是最简单的,那么很多东西就不需要我们自己做了,使用的是NGUI的示例,只针对初学者,接下来让我们来做一个最简单游戏设置里的声音控制. 1.导入NGUI: 2.找到NGUI的Menu示例Demo ...

  6. 使用泛型简单封装NGUI的ScrollView实现滑动列表

    懒,是老毛病了,周末跑了半马,跑完也是一通累,好久没锻炼了..也是懒的,有时都懒的写博客..最近看到项目中各种滑动列表框,本着要懒出水平来的原则,决定花点时间简单处理下(暂时未做列表太多时的优化):1 ...

  7. Unity NGUI 创建简单的按钮

    Unity版本:4.5.1 NGUI版本:3.6.5 注意NGUI版本,网上的大部分教程都是2.x版本的,在步骤上面略有不同,此文适合初学者. 示例: 通过NGUI创建一个背景和按钮. 1.首先创建一 ...

  8. Unity基于NGUI的简单并可直接使用的虚拟摇杆实现(一)

    可能大家都听说过大名鼎鼎的easytouch,然而easytouch是基于UGUI的,两种不同的UI混用,可能会造成项目管理的混乱,并且可能会出现各种幺蛾子,比如事件传递互相扰乱的问题. 于是就想找一 ...

  9. 【转】简单的虚拟摇杆控制移动(NGUI)

    http://www.cnblogs.com/zhangbaochong/p/4928688.html 一.用NGUI创建虚拟摇杆贴图 先创建一个sprite作为背景叫做JoyStick 并添加一个B ...

随机推荐

  1. cocos2d 走动椭圆

    1.效果图 艺术与规划说他想与我合作在全国率先主角光环加,椭圆形走动. cocos2d自带没有,參考网上的写了一个. 2.椭圆数学知识 有关椭圆的数学知识我已经忘光了.网上找了点资料: a是椭圆的长半 ...

  2. CentOS 7没有ifconfig命令处理

    新安装CentOS 7 64位后发现查看ip配置的时候没有ifconfig,百度后发现# yum install net-tools软件包即可.

  3. Wix打包系列(三)自定义Action(Custom Action)

    原文:Wix打包系列(三)自定义Action(Custom Action) 3.1 关于Action 我们已经知道如何生成具有标准安装界面的安装程序了,Windows Installer按照我们的界面 ...

  4. UVa 1292 - Strategic game (树形dp)

    本文出自   http://blog.csdn.net/shuangde800 题目链接: 点击打开链接 题目大意 给定一棵树,选择尽量少的节点,使得每个没有选中的结点至少和一个已选结点相邻. 思路 ...

  5. 阿里云server(ECS)优惠券领取

    CoderMan的博客也是放置在阿里云的ECS上.速度绝对是刚刚的,大家打开的速度肯定不会慢. 有些同志们至今可能还在用虚拟主机吧,其实阿里云server真心不贵,有俩种计费方式:各自是按月计费和按流 ...

  6. poj3694(动态询问割桥的数目)

    给我们一个图,然后有q次加边的操作,问每次加完边之后有多少个桥存在 首先用dfs求出所有的桥,然后dfs的过程中生成了一棵dfs树,该树有的边是桥,有的不是,用bridge[v] = true , 表 ...

  7. 使用SharePoint管理中心管理服务

    使用SharePoint管理中心管理服务 为了管理服务应用程序.场管理员要么使用管理中心,要么使用PowerShell. 管理服务应用程序页面列出了场上执行的服务.你能够管理他们. 很多服务都有自己的 ...

  8. Graphics.DrawString 方法

    MSDN上的解释: 在指定位置而且用指定的 Brush 和Font 对象绘制指定的文本字符串. public void DrawString( string s, Font font, Brush b ...

  9. 矩阵快速幂---BestCoder Round#8 1002

    当要求递推数列的第n项且n很大时,怎么快速求得第n项呢?可以用矩阵快速幂来加速计算.我们可以用矩阵来表示数列递推公式比如fibonacci数列 可以表示为 [f(n)   f(n-1)] = [f(n ...

  10. document.getElementById()使用方法

    document.getElementById使用 语法:oElement = document .getElementById ( sID ) 參数:sID――必选项. 字符串 (String) . ...