赞
踩
游戏中几乎都存在大大小小的背包系统,接下来我将讲述背包系统具体是如何实现的(完整源码)
以下是使用unity+NGUI实现(使用txt配置的方法,后续更新UGUI+Json实现的背包系统敬请期待!)
背包中的物品我们常常将其制作成预设体,通过改变预设体图片来产生不同的物品,以下是物品以及管理格子系统的逻辑:
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using static UnityEditor.Progress;
-
- /// <summary>
- /// 一个用于控制背包內物品的类
- /// </summary>
-
- public class InventoryItem : UIDragDropItem
- {
- //关联物品的图片
- public UISprite sprite;
- private int id;
- //关联显示窗口
- public UISprite tipWindow1;
- public UIButton tipbtnOk;
- public UIButton tipbtnCancel;
-
- void Update()
- {
-
- if (isHover)
- {
- //显示提示信息
- InventoryDes._instance.Show(id);
- if(Input.GetMouseButtonDown(1))
- {
- //按下鼠标右键开始穿戴
- //显示窗口
- tipWindow1.gameObject.SetActive(true);
- tipbtnOk.onClick.Add(new EventDelegate(() =>
- {
- bool success = EquipmentUI._instance.Dress(id);
- if(success)
- {
- transform.parent.GetComponent<InventoryItemGrid>().MinusNumber();
- }
- tipWindow1.gameObject.SetActive(false);
- }));
- tipbtnCancel.onClick.Add(new EventDelegate(() =>
- {
- tipWindow1.gameObject.SetActive(false);
- }));
-
-
- }
- }
- }
-
-
- protected override void OnDragDropRelease(GameObject surface)
- {
- base.OnDragDropRelease(surface);
-
- //测试
- if (surface != null)
- {
- if (surface.tag == Tags.inventory_item_grid)
- {
- //拖放至空格子里面
- if (surface == this.transform.parent.gameObject)
- {
- //拖放在自己的格子里面
-
- }
- else
- {
- InventoryItemGrid oldParent = this.transform.parent.GetComponent<InventoryItemGrid>();
-
- this.transform.parent = surface.transform;
- //zhuyi
- ResetPosition();
- InventoryItemGrid newParent = surface.GetComponent<InventoryItemGrid>();
-
- newParent.SetId(oldParent.id, oldParent.num);
- oldParent.ClearInfo();
- }
-
- }
- else if (surface.tag == Tags.inventory_item)
- {
- //拖放在有物品的格子里面
- InventoryItemGrid grid1 = this.transform.parent.GetComponent<InventoryItemGrid>();
- InventoryItemGrid grid2 = surface.transform.parent.GetComponent<InventoryItemGrid>();
- int id = grid1.id; int num = grid1.num;
-
- grid1.SetId(grid2.id, grid2.num);
- grid2.SetId(id, num);
- }
- else if(surface.tag==Tags.shortcut)
- {
- //拖动到快捷栏当中
- surface.GetComponent<ShortCutGrid>().SetInventory(id);
-
- }
- }
- else
- {
-
- }
- ResetPosition();
- }
- //重置位置
- void ResetPosition()
- {
- transform.localPosition = Vector3.zero;
- }
-
- //注意这里
- //public void SetId(int id)
- //{
- // ObjectInfo info=ObjectsInfo._instance.GetObjectInfoById(id);
- // sprite.spriteName = info.icon_name;
- //}
- public void SetIconName(int id, string icon_name)
- {
- sprite.spriteName = icon_name;
- this.id = id;
- }
- //public void SetIconName(string icon_name)
- //{
- // if (icon_name == null)
- // {
- // sprite.spriteName = "Icon-potion1";
- // Debug.Log("null");
- // }
- // else
- // Debug.Log("NOT NULL" + icon_name);
- // // sprite.spriteName = icon_name;
- //}
- private bool isHover = false;
- public void OnHoverOver()
- {
- isHover = true;
- }
- public void OnHoverOut()
- {
- isHover = false;
- }
- }
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- /// <summary>
- /// 一个用于管理背包內所有格子的类
- /// </summary>
- public class Inventory : MonoBehaviour
- {
- public static Inventory _instance;
- private TweenPosition tween;
- //定义金币的数量 初始化为1000
- private int coinCount = 1000;
- //使用List将格子们存储起来
- public List<InventoryItemGrid> itemGridList = new List<InventoryItemGrid>();
- //关联金币文本,控制数量
- public UILabel coinNumberLabel;
- public GameObject inventoryItem;
- //关联背包的显示和隐藏(按钮)
- public UIButton btnBag;
- public UIButton btnClose;
- private bool isShow=false;
-
- void Awake()
- {
- _instance = this;
- tween=this.GetComponent<TweenPosition>();
- }
- private void Start()
- {
- btnBag.onClick.Add(new EventDelegate(() =>
- {
- Show();
- }));
- btnClose.onClick.Add(new EventDelegate(() =>
- {
- Hide();
- }));
- }
- public void Show()
- {
- isShow=true;
- tween.PlayForward();
- }
- public void Hide()
- {
- isShow=false;
- tween.PlayReverse();
- }
- public void TransformState()
- {
- if(isShow==false)
- {
- Show();
- }
- else
- {
- Hide();
- }
-
- }
- //增加金币的方法
- public void AddCoin(int count)
- {
- coinCount += count;
- coinNumberLabel.text = coinCount.ToString();//更新金币的显示
- }
-
- //取款方法
- public bool GetCoin(int count)
- {
- if(coinCount>=count)
- {
- coinCount-=count;
- coinNumberLabel.text = coinCount.ToString();//更新金币显示
- return true;
- }
- return false;
- }
-
- //测试背包系统的方法
- void Update()
- {
- if (Input.GetKeyDown(KeyCode.X))
- {
- GetId(Random.Range(2001,2023));
- }
- }
-
- //拾取到物品 添加到物品栏里面
- //处理拾取物品的功能
- public void GetId(int id,int count=1)
- {
- //查找所有物品中是否存在该物品
- //存在就数量+1
-
- InventoryItemGrid grid = null;
- foreach (InventoryItemGrid temp in itemGridList)
- {
- if (temp.id == id)
- {
- grid = temp;
- break;
- }
- }
- if (grid != null)
- {
- grid.PlusNumber(count);
- }
- else
- {
- //不存在的情况
- foreach (InventoryItemGrid temp in itemGridList)
- {
- if (temp.id == 0)
- {
- grid = temp;
- break;
- }
- }
- //不存在就放在空的格子里面
- if (grid != null)
- {
- GameObject itemGo = NGUITools.AddChild(grid.gameObject, inventoryItem);
- itemGo.transform.localPosition = Vector3.zero;
- itemGo.GetComponent<UISprite>().depth = 4;
- grid.SetId(id,count);
- }
- }
- }
-
- public bool MinusId(int id,int count=1)
- {
-
- InventoryItemGrid grid=null;
- foreach(InventoryItemGrid temp in itemGridList)
- {
- if (temp.id == id)
- {
- grid = temp;
- break;
- }
- }
- if (grid == null)
- {
- return false;
- }
- else
- {
- bool isSuccess = grid.MinusNumber(count);
- return isSuccess;
- }
- }
- }
与物品相关的就是物品的描述了,将鼠标移动到物品上面时就会显示物品的信息,那么物品显示又应该怎么制作呢?废话不多说,直接上代码:
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- /// <summary>
- /// 一个用于控制物品信息显示的类
- /// </summary>
- public class InventoryDes : MonoBehaviour
- {
- public static InventoryDes _instance;
- public UILabel label;
- //计时器
- private float timer = 0;
-
- void Awake()
- {
- _instance = this;
-
- this.gameObject.SetActive(false);
- }
- void Update()
- {
- if (this.gameObject.activeInHierarchy == true)
- {
- timer -= Time.deltaTime;
- if (timer <= 0)
- {
- this.gameObject.SetActive(false);
- }
- }
- }
- //显示的方法
- public void Show(int id)
- {
- this.gameObject.SetActive(true);
- timer = 0.1f;
- transform.position = UICamera.currentCamera.ScreenToWorldPoint(Input.mousePosition);
- ObjectInfo info = ObjectsInfo._instance.GetObjectInfoById(id);
- string des = "";
- switch (info.type)
- {
- case ObjectType.Drug:
- des = GetDrugDes(info);
- break;
- case ObjectType.Equip:
- des = GetEquipDes(info);
- break;
- }
- //更新显示
- label.text = des;
- }
- string GetDrugDes(ObjectInfo info)
- {
- string str = "";
- str +="名称:" + info.name + "\n";
- str += "+HP:" + info.hp + "\n";
- str += "+MP:" + info.mp + "\n";
- str += "出售价:" + info.price_sell + "\n";
- str += "购买价:" + info.price_buy;
- return str;
- }
-
- string GetEquipDes(ObjectInfo info)
- {
- string str = "";
- str += "名称" + info.name + "\n";
- switch(info.dressType)
- {
- case DressType.Headgear:
- str += "穿戴类型:头盔\n";
- break;
- case DressType.Armor:
- str += "穿戴类型:盔甲\n";
- break;
- case DressType.LeftHand:
- str += "穿戴类型:左手\n";
- break;
- case DressType.RightHand:
- str += "穿戴类型:右手\n";
- break;
- case DressType.Shoe:
- str += "穿戴类型:鞋\n";
- break;
- case DressType.Accessory:
- str += "穿戴类型:饰品\n";
- break;
-
- }
- switch(info.applicationType)
- {
- case ApplicationType.Swordman:
- str += "适用类型:剑士\n";
- break;
- case ApplicationType.Magician:
- str += "适用类型:魔法师\n";
- break;
- case ApplicationType.Common:
- str += "适用类型:通用\n";
- break;
- }
- str += "伤害值:" + info.attack + "\n";
- str += "防御值:" + info.def + "\n";
- str += "速度值:" + info.speed + "\n";
- return str;
- }
- }
-
格子的逻辑:
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- /// <summary>
- /// 一个用于控制背包单个格子的类
- /// </summary>
- public class InventoryItemGrid : MonoBehaviour
- {
- public static InventoryItemGrid _instance;
- public int id = 0;
- private ObjectInfo info = null;
- public int num = 0;
- public UILabel numLabel;
-
- void Awake()
- {
- _instance = this;
- //一开始隐藏文本
- numLabel.enabled= false;
- }
-
- public void SetId(int id, int num = 1)
- {
- this.id = id;
- info = ObjectsInfo._instance.GetObjectInfoById(id);
-
- InventoryItem item = this.GetComponentInChildren<InventoryItem>();
-
-
- item.SetIconName(id, info.icon_name);
-
- numLabel.enabled = true;
- this.num = num;
- numLabel.text = num.ToString();
- }
- public void PlusNumber(int num = 1)
- {
-
- this.num += num;
- //更新显示
- numLabel.text = this.num.ToString();
-
- }
-
- //用于减去数量的 表示装备是否减去成功
- public bool MinusNumber(int num=1)
- {
-
- if(this.num>=num)
- {
- this.num -= num;
- numLabel.text = this.num.ToString();
- if(this.num==0)
- {
- //清空物品
- ClearInfo();
- GameObject.Destroy(this.GetComponentInChildren<InventoryItem>().gameObject);
- }
- return true;
- }
- return false;
- }
-
- //public void PlusNumber(int num = 1)
- //{
- // if (this.num < 10)
- // {
- // this.num = num + this.num;
-
- // //更新显示
- // numLabel.text = this.num.ToString();
- // if (this.num <= 1)
- // numLabel.enabled = false;
- // else
- // numLabel.enabled = true;
- // }
- //}
- //设置一个清空的方法
- public void ClearInfo()
- {
- id = 0;
- info = null;
- num = 0;
- numLabel.enabled = false;
- }
- }
其中最最重要的就是接下来的类了,一个关于物品信息的类,有了它才能操控背包系统正常运作,其中文本读取的是txt的文本,其中的定义规则你可以自己定义,然后拿给策划填写就可以了,注意不要空格!!!!而且符号是英文的符号,更重要的一点是你脚本里面写的一定要和策划填写的一样!如果出现报空错误一定要仔细检查txt文本是否有误,一定要让策划仔细检查三遍!!!!!(我之前是这样写的,结果我的其它协作者使用报错了,原因是策划期间修改了文本,并且没有仔细检查,所以大家一定要注意!)
以下是完整代码:
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
-
- /// <summary>
- /// 一个用于管理所有Object对象信息的类
- /// </summary>
- public class ObjectsInfo : MonoBehaviour
- {
- public static ObjectsInfo _instance;
- //使用字典的方法存储起来 默认为空
- //使用ID拿取物品
- public Dictionary<int, ObjectInfo> objectInfoDict = new Dictionary<int, ObjectInfo>();
- //可读取文本
- public TextAsset objectsInfoListText;
- void Awake()
- {
- _instance = this;
- //测试是否成功
- ReadInfo();
-
- }
-
- /// <summary>
- /// 写一个向外界提供物品信息的方法
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- public ObjectInfo GetObjectInfoById(int id)
- {
- ObjectInfo info = null;
- //根据ID获取信息
- objectInfoDict.TryGetValue(id, out info);
- return info;
- }
-
- //写一个读取的类
- void ReadInfo()
- {
- string text = objectsInfoListText.text;
- //拆分一行
- string[] strArray = text.Split('\n');
- //将每一行都拆分成一个一个的
- foreach (string str in strArray)
- {
- string[] proArray = str.Split(',');
- //new一个ObjectInfo存储物品信息
- ObjectInfo info = new ObjectInfo();
- //将文本一行内容一个一个读取,存到新new的对象里面去
- int id = int.Parse(proArray[0]);
- string name = proArray[1];
- string icon_name = proArray[2];
- string str_type = proArray[3];
- //首先定义一种类型
- ObjectType type = ObjectType.Drug;
- switch (str_type)
- {
- case "Drug":
- type = ObjectType.Drug;
- break;
- case "Equip":
- type = ObjectType.Equip;
- break;
- case "Mat":
- type = ObjectType.Mat;
- break;
- //其它的物品种类就在后面添加即可
- }
- //存进去
- info.id = id; info.name = name; info.icon_name = icon_name; info.type = type;
- //药品系列赋值
- if (type == ObjectType.Drug)
- {
- int hp = int.Parse(proArray[4]);
- int mp = int.Parse(proArray[5]);
- int price_sell = int.Parse(proArray[6]);
- int price_buy = int.Parse(proArray[7]);
- //存进去
- info.hp = hp;
- info.mp = mp;
- info.price_sell = price_sell;
- info.price_buy = price_buy;
- }
-
- //装备系列赋值
- if(type==ObjectType.Equip)
- {
- info.attack = int.Parse(proArray[4]);
- info.def = int.Parse(proArray[5]);
- info.speed = int.Parse(proArray[6]);
- info.price_sell = int.Parse(proArray[9]);
- info.price_buy = int.Parse(proArray[10]);
- string str_dresstype = proArray[7];
- switch(str_dresstype)
- {
- case "Headgear":
- info.dressType = DressType.Headgear;
- break;
- case "Armor":
- info.dressType = DressType.Armor;
- break;
- case "LeftHand":
- info.dressType = DressType.LeftHand;
- break;
- case "RightHand":
- info.dressType = DressType.RightHand;
- break;
- case "Shoe":
- info.dressType = DressType.Shoe;
- break;
- case "Accessory":
- info.dressType = DressType.Accessory;
- break;
- }
- string str_apptype = proArray[8];
- switch(str_apptype)
- {
- case "Swordman":
- info.applicationType = ApplicationType.Swordman;
- break;
- case "Magician":
- info.applicationType = ApplicationType.Magician;
- break;
- case "Common":
- info.applicationType = ApplicationType.Common;
- break;
- }
- }
- //将他们添加到字典之中
- objectInfoDict.Add(id, info);
- }
- }
- }
-
- /// <summary>
- /// 用于管理物品种类的枚举
- /// 建立一个枚举 方便日后更多品种的物品信息添加
- /// </summary>
- public enum ObjectType
- {
- //药品系列
- Drug,
- Equip,
- Mat
- }
-
- /// <summary>
- /// 用于处理装备的信息
- /// </summary>
- public enum DressType
- {
- Headgear,
- Armor,
- RightHand,
- LeftHand,
- Shoe,
- Accessory
- }
-
- /// <summary>
- /// 用于处理不同类型的信息
- /// </summary>
- public enum ApplicationType
- {
- Swordman,//剑士
- Magician,//魔法师
- Common//通用
- }
-
- /// <summary>
- /// 一个用于管理单个物品信息的类
- /// </summary>
- public class ObjectInfo
- {
- public int id; //索引值
- public string name; //物品名字
- public string icon_name; //物品加载的图片名字(存图集的名字)
- public ObjectType type; //物品的种类
- public int hp; //添加的HP值
- public int mp; //添加的MP值
- public int price_sell; //售卖的价格
- public int price_buy; //卖出的价格(玩家)
-
- public int attack;
- public int def;
- public int speed;
- public DressType dressType;
- public ApplicationType applicationType;
- }
以上是背包系统的完整代码,如果你直接复制发现了报错,那可能是因为我在里面关联了其它系统,找出来修改一下就好了,或者直接问我,核心的内容就是这些,希望对你有所帮助,点个赞支持一下吧!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。