基于Unity3D(UGUI)的背包系统<三>
来源:互联网 发布:牛扒和牛排区别知乎 编辑:程序博客网 时间:2024/05/01 23:46
这一篇,主要讲解UI逻辑处理方面,以及UI和该篇中的数据两者之间的使用。
首先补充一个上篇中缺少的一个配方类:这个类主要是用来保存锻造的所需的材料及锻造出来的结果。
using UnityEngine;using System.Collections;using System.Collections.Generic;/// <summary>/// 配方类:用来保存锻造的所需的材料及锻造出来的结果/// </summary>public class Formula{ public int Item1ID { get; private set; }//用来锻造的物品1的ID public int Item1Amount { get; private set; }//用来锻造的物品1的数量 public int Item2ID { get; private set; }//用来锻造的物品2的ID public int Item2Amount { get; private set; }//用来锻造的物品2的数量 public int ResID { get; set; }//保存锻造结果的ID private List<int> needIDList = new List<int>();//保存锻造所需要材料的ID(相当于锻造的配方) public List<int> NeedIDList { get { return needIDList; } } public Formula(int item1ID, int item1Amount, int item2ID, int item2Amount, int resID ) { this.Item1ID = item1ID; this.Item1Amount = item1Amount; this.Item2ID = item2ID; this.Item2Amount = item2Amount; this.ResID = resID; //初始化配方ID for (int i = 0; i < Item1Amount; i++) { needIDList.Add(Item1ID); } for (int i = 0; i < Item2Amount; i++) { needIDList.Add(Item2ID); } } /// <summary> /// 匹配所提供的物品是否 包含 锻造所需要的物品(利用ID匹配) /// </summary> /// <returns></returns> public bool Match( List<int> idList ) { List<int> tempIDList = new List<int>(idList);//临时保存函数参数数据(所拥有的物品ID),防止下面Remove代码移除时被修改 foreach (int id in needIDList) { bool isSuccess = tempIDList.Remove(id); if (isSuccess == false) { return false;//拥有的物品和锻造所需的物品匹配失败 } } return true;//物品匹配成功 }}
接着,重点部分就来了。正如第一部分图中那样。总的有5个面板:背包面板,箱子面板,角色面板,商店小贩面板,以及锻造面板。其中,每一个面板都有一个基类(Inventory类),因为这些面板中有一些相似的功能和方法,所以选择使用了继承。各自对应的代码如下:
①基类Inventory:
using UnityEngine;using System.Collections;using System.Collections.Generic;using System.Text;/// <summary>///存货类, 背包和箱子的基类/// </summary>public class Inventroy : MonoBehaviour { protected Slot[] slotArray;//存放物品槽的数组 //控制背包的显示和隐藏相关变量 private float targetAlpha = 1f;//显示目标值 private float smothing = 4f;//渐变平滑速度 private CanvasGroup canvasGroupMy; public CanvasGroup CanvasGroupMy //对CanvasGroup的引用,用于制作隐藏显示效果 { get { if (canvasGroupMy == null) { canvasGroupMy = GetComponent<CanvasGroup>(); } return canvasGroupMy; } } // Use this for initialization public virtual void Start () {//声明为虚函数,方便子类重写 slotArray = GetComponentsInChildren<Slot>(); if (canvasGroupMy == null) { canvasGroupMy = GetComponent<CanvasGroup>(); } } void Update() { if (this.CanvasGroupMy.alpha != targetAlpha) { this.CanvasGroupMy.alpha = Mathf.Lerp(this.CanvasGroupMy.alpha, targetAlpha, smothing * Time.deltaTime); if (Mathf.Abs(this.CanvasGroupMy.alpha - targetAlpha)<.01f) { this.CanvasGroupMy.alpha = targetAlpha; } } } //根据Id存储物品 public bool StoreItem(int id) { Item item = InventroyManager.Instance.GetItemById(id); return StoreItem(item); } //根据Item存储物品(重点) public bool StoreItem(Item item) { if (item.ID == 0) { Debug.LogWarning("要存储物品的ID不存在"); return false; } if (item.Capacity == 1)//如果此物品只能放一个,那就找一个空的物品槽来存放即可 { Slot slot = FindEmptySlot(); if (slot == null)//如果空的物品槽没有了 { Debug.LogWarning("没有空的物品槽可供使用"); return false;//存储失败 } else //空的物品槽还有,那就把物品添加进去 { slot.StoreItem(item); } } else//如果此物品能放多个 { Slot slot = FindSameIDSlot(item); if (slot != null)//找到了符合条件的物品槽,那就把物品存起来 { slot.StoreItem(item); } else //没有找到符合条件的物品槽,那就找一个没有存放物品的物品槽去存放物品 { Slot emptySlot = FindEmptySlot(); if (emptySlot != null) { emptySlot.StoreItem(item);//空的物品槽去存放物品 } else // 如果连空的物品槽,也就是没有存储物品的物品槽都找不到 { Debug.LogWarning("没有空的物品槽可供使用"); return false;//存储失败 } } } return true; //存储成功 } //寻找空的物品槽 private Slot FindEmptySlot() { foreach (Slot slot in slotArray) { if (slot.transform.childCount == 0)//物品槽下面无子类,说明该物品槽为空,返回它即可 { return slot; } } return null; } //查找存放的物品是相同的物品槽 private Slot FindSameIDSlot(Item item) { foreach (Slot slot in slotArray) { //如果当前的物品槽已经有物品了,并且里面的物品的类型和需要找的类型一样,并且物品槽还没有被填满 if (slot.transform.childCount >= 1 && item.ID == slot.GetItemID() && slot.isFiled() == false) { return slot; } } return null; } //面板的显示方法 public void Show() { this.CanvasGroupMy.blocksRaycasts = true;//面板显示时为可交互状态 this.targetAlpha = 1; } //面板的隐藏方法 public void Hide() { this.CanvasGroupMy.blocksRaycasts = false;//面板隐藏后为不可交互状态 this.targetAlpha = 0; } //控制面板的显示及隐藏关系 public void DisplaySwitch() { if (this.CanvasGroupMy.alpha == 0) { Show(); } if (this.CanvasGroupMy.alpha == 1) { Hide(); } } //控制物品信息的保存(ID,Amount数量) public void SaveInventory() { StringBuilder sb = new StringBuilder();//用来保存物品信息的字符串 foreach (Slot slot in slotArray) { if (slot.transform.childCount > 0 ) { ItemUI itemUI = slot.transform.GetChild(0).GetComponent<ItemUI>(); sb.Append(itemUI.Item.ID + "," + itemUI.Amount + "-");//用逗号分隔一个物品中的ID和数量,用 - 分隔多个物品 } else { sb.Append("0-");//如果物品槽里没有物品就是0 } } PlayerPrefs.SetString(this.gameObject.name, sb.ToString());//保存字符串数据 } //控制物品信息的加载(根据ID,Amount数量) public void LoadInventory() { if (PlayerPrefs.HasKey(this.gameObject.name) == false) return;//判断保存的这个关键码Key是否存在,不存在就不做处理 string str = PlayerPrefs.GetString(this.gameObject.name);//获取上面保存的字符串数据 string[] itemArray = str.Split('-');//按照 - 分隔多个物品 for (int i = 0; i < itemArray.Length-1; i++)//长度减1是因为最后一个字符是 “-”,不需要取它 { string itemStr = itemArray[i]; if (itemStr != "0") { string[] temp = itemStr.Split(',');//按照逗号分隔这个物品的信息(ID和Amoun数量) int id = int.Parse(temp[0]); Item item = InventroyManager.Instance.GetItemById(id);//通过物品ID得到该物品 int amount = int.Parse(temp[1]); for (int j = 0; j < amount; j++)//执行Amount次StoreItem方法,一个一个的存 { slotArray[i].StoreItem(item); } } } }}
②背包面板:
using UnityEngine;
using System.Collections;
///
/// 背包类,继承自 存货类Inventroy
///
public class Knapscak : Inventroy {
//单例模式
private static Knapscak _instance;
public static Knapscak Instance {
get {
if (_instance == null)
{
_instance = GameObject.Find(“KnapscakPanel”).GetComponent();
}
return _instance;
}
}
}
③箱子面板
using UnityEngine;using System.Collections;/// <summary>/// 箱子类,继承自 存货类Inventroy/// </summary>public class Chest : Inventroy { //单例模式 private static Chest _instance; public static Chest Instance { get { if (_instance == null) { _instance = GameObject.Find("ChestPanel").GetComponent<Chest>(); } return _instance; } }}
④角色面板
using UnityEngine;using System.Collections;using UnityEngine.UI;/// <summary>/// 角色面板类,控制角色面板的逻辑/// </summary>public class CharacterPanel : Inventroy{ //单例模式 private static CharacterPanel _instance; public static CharacterPanel Instance { get { if (_instance == null) { _instance = GameObject.Find("CharacterPanel").GetComponent<CharacterPanel>(); } return _instance; } } private Text characterPropertyText;//对角色属性面板中Text组件的引用 private Player player;//对角色脚本的引用 public override void Start() { base.Start(); characterPropertyText = transform.Find("CharacterPropertyPanel/Text").GetComponent<Text>(); player = GameObject.FindWithTag("Player").GetComponent<Player>(); UpdatePropertyText();//初始化显示角色属性值 } //更新角色属性显示 private void UpdatePropertyText() { int strength = 0, intellect = 0, agility = 0, stamina = 0, damage = 0; foreach (EquipmentSlot slot in slotArray)//遍历角色面板中的装备物品槽 { if (slot.transform.childCount > 0)//找到有物品的物品槽,获取里面装备的属性值 { Item item = slot.transform.GetChild(0).GetComponent<ItemUI>().Item; if (item is Equipment)//如果物品是装备,那就加角色对应的属性 { Equipment e = (Equipment)item; strength += e.Strength; intellect += e.Intellect; agility += e.Agility; stamina += e.Stamina; } else if (item is Weapon)///如果物品是武器,那就加角色的伤害(damage)属性 { Weapon w = (Weapon)item; damage += w.Damage; } } } strength += player.BasicStrength; intellect += player.BasicIntellect; agility += player.BasicAgility; stamina += player.BasicStamina; damage += player.BasicDamage; string text = string.Format("力量:{0}\n智力:{1}\n敏捷:{2}\n体力:{3}\n攻击力:{4}\n", strength, intellect, agility, stamina, damage); characterPropertyText.text = text; } //直接穿戴功能(不需拖拽) public void PutOn(Item item) { Item exitItem = null;//临时保存需要交换的物品 foreach (Slot slot in slotArray)//遍历角色面板中的物品槽,查找合适的的物品槽 { EquipmentSlot equipmentSlot = (EquipmentSlot)slot; if (equipmentSlot.IsRightItem(item)) //判断物品是否合适放置在该物品槽里 { if (equipmentSlot.transform.childCount > 0)//判断角色面板中的物品槽合适的位置是否已经有了装备 { ItemUI currentItemUI = equipmentSlot.transform.GetChild(0).GetComponent<ItemUI>(); exitItem = currentItemUI.Item; currentItemUI.SetItem(item, 1); } else { equipmentSlot.StoreItem(item); } break; } } if (exitItem != null) { Knapscak.Instance.StoreItem(exitItem);//把角色面板上是物品替换到背包里面 } UpdatePropertyText();//更新显示角色属性值 } //脱掉装备功能(不需拖拽) public void PutOff(Item item) { Knapscak.Instance.StoreItem(item);//把角色面板上是物品替换到背包里面 UpdatePropertyText();//更新显示角色属性值 }}
⑤商店小贩面板
using UnityEngine;using System.Collections;public class Vendor : Inventroy { //单例模式 private static Vendor _instance; public static Vendor Instance { get { if (_instance == null) { _instance = GameObject.Find("VendorPanel").GetComponent<Vendor>(); } return _instance; } } public int[] itemIdArray;//一个物品ID的数组,用于给商贩初始化 private Player player;//对主角Player脚本的引用,用于购买物品功能 public override void Start() { base.Start(); InitShop(); player = GameObject.FindWithTag("Player").GetComponent<Player>(); Hide(); } //初始化商贩 private void InitShop() { foreach (int itemId in itemIdArray) { StoreItem(itemId); } } //主角购买物品 public void BuyItem(Item item) { bool isSusscess = player.ConsumeCoin(item.BuyPrice);//主角消耗金币购买物品 if (isSusscess) { Knapscak.Instance.StoreItem(item); } } //主角售卖物品 public void SellItem() { int sellAmount = 1;//销售数量 if (Input.GetKey(KeyCode.LeftControl))//按住坐标Ctrl键物品一个一个的售卖,否则全部售卖 { sellAmount = 1; } else { sellAmount = InventroyManager.Instance.PickedItem.Amount; } int coinAmount = InventroyManager.Instance.PickedItem.Item.SellPrice * sellAmount;//售卖所获得的金币总数 player.EarnCoin(coinAmount);//主角赚取到售卖物品的金币 InventroyManager.Instance.ReduceAmountItem(sellAmount);//鼠标上的物品减少或者销毁 }}
⑥锻造面板
using UnityEngine;using System.Collections;using System.Collections.Generic;/// <summary>/// 锻造类:实现材料锻造成装备或者武器/// </summary>public class Forge : Inventroy { //单例模式 private static Forge _instance; public static Forge Instance { get { if (_instance == null) { _instance = GameObject.Find("ForgePanel").GetComponent<Forge>(); } return _instance; } } private List<Formula> formulaList = null;//用来存放解析出来的材料 public override void Start() { base.Start(); ParseFormulaJSON(); Hide(); } //解析武器锻造配方Jso文件 public void ParseFormulaJSON() { formulaList = new List<Formula>(); TextAsset formulaText = Resources.Load<TextAsset>("Formulas"); string formulaJson = formulaText.text; JSONObject jo = new JSONObject(formulaJson); foreach (JSONObject temp in jo.list) { int item1ID = (int)temp["Item1ID"].n; int item1Amount = (int)temp["Item1Amount"].n; int item2ID = (int)temp["Item2ID"].n; int item2Amount = (int)temp["Item2Amount"].n; int resID = (int)temp["ResID"].n; Formula formula = new Formula(item1ID, item1Amount, item2ID, item2Amount, resID); formulaList.Add(formula); } //Debug.Log(formulaList[1].ResID); } /// <summary> /// 锻造物品功能:重点 /// </summary> public void ForgeItem() { //得到当前锻造面板里面有哪些材料 List<int> haveMaterialIDList = new List<int>();//存储当前锻造面板里面拥有的材料的ID foreach (Slot slot in slotArray) { if (slot.transform.childCount > 0) { ItemUI currentItemUI = slot.transform.GetChild(0).GetComponent<ItemUI>(); for (int i = 0; i < currentItemUI.Amount; i++) { haveMaterialIDList.Add(currentItemUI.Item.ID);//物品槽里有多少个物品,就存储多少个ID } } } //Debug.Log(haveMaterialIDList[0].ToString()); //判断满足哪一个锻造配方的需求 Formula matchedFormula = null; foreach (Formula formula in formulaList) { bool isMatch = formula.Match(haveMaterialIDList); //Debug.Log(isMatch); if (isMatch) { matchedFormula = formula; break; } } // Debug.Log(matchedFormula.ResID); if (matchedFormula != null) { Knapscak.Instance.StoreItem(matchedFormula.ResID);//把锻造出来的物品放入背包 //减掉消耗的材料 foreach (int id in matchedFormula.NeedIDList) { foreach (Slot slot in slotArray) { if (slot.transform.childCount > 0) { ItemUI itemUI = slot.transform.GetChild(0).GetComponent<ItemUI>(); if (itemUI.Item.ID == id && itemUI.Amount > 0) { itemUI.RemoveItemAmount(); if (itemUI.Amount <= 0) { DestroyImmediate(itemUI.gameObject); } break; } } } } } }}
阅读全文
1 0
- 基于Unity3D(UGUI)的背包系统<三>
- 基于Unity3D(UGUI)的背包系统<二>
- 基于Unity3D(UGUI)的背包系统<四>完结篇
- 基于Unity3D(UGUI)的背包系统(装备系统,锻造系统,购买系统)
- Unity3D自学笔记——UGUI背包系统(三)物品弹出提示框
- Unity3D自学笔记——UGUI背包系统(七)物品的装备与卸下
- Unity3D自学笔记——UGUI背包系统(八)物品的分类与整理
- Unity3D——UGUI实现背包系统
- 【Unity】基于MVC模式的背包系统 UGUI实现
- UGUI的背包系统(上)
- Unity3D自学笔记——UGUI背包系统(九)装备对HP影响的逻辑及使用药品
- UGUI--背包系统之三--------Slot
- UGUI背包系统(初级)
- UGUI背包系统(中)
- UGUI背包系统(下)
- Unity3D自学笔记——UGUI背包系统(一)ItemData
- Unity3D自学笔记——UGUI背包系统(二)UI设计实现及数据绑定
- Unity3D自学笔记——UGUI背包系统(四)角色物品数据建立
- Android之-四大组件五大存储
- get请求表单的action属性后不能带参数
- Thinking in Java 读书笔记 (一)
- 第42章 z域分析(中)
- pycharm进行字体大小调整
- 基于Unity3D(UGUI)的背包系统<三>
- Mac安装Node环境和设置npm镜像
- struts-入门 登陆 maven 构建
- Web基础之Servlet+JDBC+JSP项目实战记录(二)
- WorkStation创建linux虚拟机
- Libgdx专题系列:物理引擎篇 Box2D
- CodeFroces 814A An abandoned sentiment from past(快排)
- Android studio 初步使用JNI(二)制作.so库
- PopWindows 底部显示与隐藏