查看: 72398|回复: 134

4.1 道具系统补全:合成系统 UI 前言

[复制链接]

1

主题

342

帖子

7万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
75866
发表于 2014-11-5 19:40:02 | 显示全部楼层 |阅读模式
4.1 道具系统补全:合成系统 & UI 前言

【爆甲英雄传】4.背包系统



本篇原本属于UI的,但是作为一个负责任的茶水,在回顾之前的帖子的时候,发现漏了一个很重要的功能,就是合成系统,我们在设计道具的时候,已经设计好了配方这个类型的道具,但是,在背包系统中却没有合成的功能,这样可不行啊,合成是一个游戏的精髓啊,所以,确定本篇乱入,补全道具系统的核心代码,当让,最后附上测试单元,这样就可以测试合成这一块了,具体的新UI demo(含合成功能),将会随下篇一起附上。

好了,这次其实不用什么新建什么脚本了,我们只要修改之前的就可以了。 照旧,最后附上全部代码。

Inventory_Manager 里添加新的函数

public int Get_Amount_Item(int itemID, Inventory_Type type), 返回道具的数量,用于判断是否有足够的材料制作新道具,若道具不熏在,返回-1。道具ID,背包类型。

public bool Has_Item(int itemID, Inventory_Type type),是否拥有指定道具,简单不解释。道具ID,背包类型。

public bool Can_Create_Item(int recipeID, Inventory_Type type),判断是否能制作新的道具,主要判定是否有足够材料。配方的道具ID,背包类型。

public Item_Profile Create_Item(int recipeID, Inventory_Type type),制作道具,返回道具的描述文件(脚本或类型),并移除材料,配方保留。配方的道具ID,背包类型。(注意,正常的合成系统应该只能在玩家的背包或仓库才能进行的,所以外部调用的时候,需要判断好背包类型的合法性。UI篇里会继续探讨。)

Unit_Inventory_ManagerUnit_Inventory_Manager_Editor 只是添加了一个提供测试函数而已,没什么也别。但是值得注意的是,Unit_Inventory_Manager 中的参数 itemInfo 返回一个新制作出来的道具,用于快速定位而已,可无视。

复制到好新的代码,然后设计好你的配方,保证你的背包有足够的材料,然后。。。合成吧。

好了,到目前位置,字数不够,没有贴图,这样发文肯定会被打的,怎么办的,一个字,磨!磨多点字出来呗,那茶水就趁这个时间给大家预热下UI篇吧。


================咸湿分割线================

UI 前言

首先,下载好NGUI,最新不最新到不重要,重要的是不要太旧。然后茶水假设大家都有一定程度的NGUI的开发经验,如果你是第一次使用NGUI,可以看看其他蛮牛大神的帖子。

然后,上图:

4.1 道具系统补全:合成系统 & UI 前言

是不是吓死人呢,哈哈,不要怕,茶水也是这么过来的。首先,我们来一步步的分解他的结构,

4.1 道具系统补全:合成系统 & UI 前言

NGUI的一些基本元素,例如UI Camera,UI Root这些就不用多说了,我们主要集中在System Buttons和后面6个UI xXXX的蓝色字就好了。

4.1 道具系统补全:合成系统 & UI 前言

这6个元素在层级机构中都属于同一级,我们点击其中一个来看看他的组件成员。

如图所示,我们看到的是System Buttons这一块,他所包含的是一个UIPanel,所以我们这个层级的元素全都是UIPanel,这样组织绝对只是NGUI的结构所限,NGUI提供了一个很好的层级间相互叠加的一个管理,用UIPanel的目的就是方便实现次管理,简单说,就是面板间的前后遮挡问题,2D中最常见的问题。好了,这里不用深究这个问题,这不是我们的重点,我只是在磨字数而已。

[size=13.63636302948px]================咸湿分割线================

现在开始讲解各个各个面板的功能。

System Buttons,就是一个基本界面,目的提供一些常用的界面操作,返回主菜单,或且开关某个指定的面板,直接提供一组系统级的按钮,这里我们看到他下挂了一个Windows Reset对象,它是一个按钮,重置所以面板,方便测试而已。

4.1 道具系统补全:合成系统 & UI 前言

UI Itembase review windows, 这个面板用于查看我们的道具系统中的道具数据库,主要用于测试而已,提供一种可视化的方式去检测我们设计好的道具,实际游戏中这个面板并不需要。大家看到它的层级结构,是不是很吓人呢,其实很多都是NGUI中的布局元素,主要的在Panel下的元素,这些后篇会详细说明。

4.1 道具系统补全:合成系统 & UI 前言

UI Store Inventory windows,仓库面板,不解释。

4.1 道具系统补全:合成系统 & UI 前言

UI Player Inventory windows, UI Shop Inventory windows,玩家背包面板和商店面板,不解释too。

4.1 道具系统补全:合成系统 & UI 前言

UI Description windows,描述面板,就是道具的描述,当你点击某个道具的时候,这个面板就是显示玩家所选择的道具一些详情。我们可以看到它下挂了各种UI Description X,根据玩家所选择的道具,切换不用的面板用于显示不用的类型的道具,如果你新增了新的道具类型,这里也需要新增一个与之对应的面板用于显示。然后,懒的话也可以设计一个通用的面板,最简单的就是很多手机或掌机最常用的办法,就是设计一个仅有一个text box的面板,是不是很通用呢。哈哈。

OK,基本的层级结构终于讲完了,理论的东西总是这个鼓噪无味,希望大家没有睡着了,不知道大家有没有留意到,这里有个元素经常出现在各大面板中,没错,它就是 Item Slot X,这个就是传说中的道具格或道具槽,这个东西是道具UI中最重要的组成部分,也是最小的一个单元,我们先来偷窥下它的结构,

4.1 道具系统补全:合成系统 & UI 前言


别怕,众多组件都是NGUI自带的,我们需要做的就是编写一个UI_Item_Slot而已,而且还是用你们最喜爱的C#,是不是很简单呢。Item Slot主要提供一个显示道具图标,名称,数量和基本的拖放操作。

投票部分:

由于UI的设计不是一般的痛苦,由于UI中的代码都是环环紧扣,交叉性比较大,所以一篇下来,给出的代码可能还不能用,因为需要后篇的别的代码的支持,所以茶水在此想发起一个投票,看看大家的意愿,大家回帖表达意愿就好了,貌似不能发起投票。

1.先全部设计好UI元素再设计代码。(默认)
2.边设计UI元素边设计代码。
3.都行。

  1. Inventory_Manager

  2. using UnityEngine;

  3. using System.Collections;

  4. using System.Collections.Generic;



  5. [System.Serializable]

  6. public class Inventory_Manager : MonoBehaviour {



  7.         public int money;



  8.         List<Inventory_Slot> current_inventory;

  9.         int current_limit;



  10.         public List<Inventory_Slot> player_inventory;

  11.         int player_inventory_limit = 40;

  12.         public List<Inventory_Slot> store_inventory;

  13.         int store_inventory_limit = 99999; // infinite almost

  14.         public List<Inventory_Slot> shop_inventory;

  15.         int shop_inventory_limit = 99999; // infinite almost



  16.         static Inventory_Manager im;



  17.         #region Equipment

  18.         public int

  19.                 equipmentID_Main_Weapon = -1,

  20.                 equipmentID_Second_Weapon = -1,

  21.                 equipmentID_Shield = -1,

  22.                 equipmentID_Head = -1,

  23.                 equipmentID_Shoulder = -1,

  24.                 equipmentID_Belt = -1;

  25.         // add more equipment here ...

  26.         #endregion





  27.         public enum Inventory_Type

  28.         {

  29.                 Player,

  30.                 Store,

  31.                 Shop,

  32.                 None

  33.         };





  34.         // Use this for initialization

  35.         void Awake ()

  36.         {

  37.                 DontDestroyOnLoad(gameObject);

  38.                 im = gameObject.GetComponent<Inventory_Manager>();

  39.         }



  40.         public static Inventory_Manager Get_Manager()

  41.         {

  42.                 if (im == null)

  43.                 {

  44.                         Global_Manager.InitAll();

  45.                 }

  46.                 return im;

  47.         }



  48.         void Select_Inventory(Inventory_Type type)

  49.         {



  50.                 switch (type)

  51.                 {

  52.                 case Inventory_Type.Player:

  53.                         current_inventory = player_inventory;

  54.                         current_limit = player_inventory_limit;

  55.                         break;

  56.                 case Inventory_Type.Store:

  57.                         current_inventory = store_inventory;

  58.                         current_limit = store_inventory_limit;

  59.                         break;

  60.                 case Inventory_Type.Shop:

  61.                         current_inventory = shop_inventory;

  62.                         current_limit = shop_inventory_limit;

  63.                         break;

  64.                 default:

  65.                         current_inventory = null;

  66.                         current_limit = 0;

  67.                         break;

  68.                 }

  69.         }



  70.         public bool Deposit(int itemID, Inventory_Type type)

  71.         {

  72.                 Select_Inventory(type);

  73.                 if (null == current_inventory)

  74.                         return false;



  75.                 Inventory_Slot slot = Current_Slot(itemID,true);

  76.                 if (slot !=null)

  77.                 {



  78.                         if (slot.Deposit())

  79.                         {

  80.                                 return true;

  81.                         }

  82.                         else

  83.                         {

  84.                                 // add a new stack

  85.                                 return Add_New_Slot(itemID);

  86.                         }

  87.                 }

  88.                 else

  89.                 {

  90.                         // add a new stack

  91.                         return Add_New_Slot(itemID);



  92.                 }



  93.                 return false;

  94.         }





  95.         public bool Withdraw(int itemID, Inventory_Type type)

  96.         {

  97.                 Select_Inventory(type);

  98.                 if (null == current_inventory)

  99.                         return false;



  100.                 Inventory_Slot slot = Current_Slot(itemID,false);



  101.                 if (slot != null)

  102.                 {



  103.                         if (slot.Withdraw())

  104.                         {

  105.                                 current_inventory.Remove(slot);

  106.                         }



  107.                         return true;

  108.                 }



  109.                 return false;

  110.         }



  111.         public bool Withdraw_at_slot(int slotID, Inventory_Type type)

  112.         {

  113.                 Select_Inventory(type);

  114.                 if (null == current_inventory)

  115.                         return false;



  116.                 Inventory_Slot slot = current_inventory[slotID];



  117.                

  118.                 if (slot != null)

  119.                 {

  120.                         

  121.                         if (slot.Withdraw())

  122.                         {

  123.                                 current_inventory.Remove(slot);

  124.                         }

  125.                         

  126.                         return true;

  127.                 }

  128.                

  129.                 return false;

  130.         }



  131.         public int Get_Current_Stack(int slotID, Inventory_Type type)

  132.         {

  133.                 Select_Inventory(type);

  134.                 if (null == current_inventory)

  135.                         return -1;

  136.                 return current_inventory[slotID].current_stack;

  137.         }





  138.         Inventory_Slot Current_Slot(int itemID, bool deposit)

  139.         {

  140.                 if (deposit)

  141.                 {

  142.                         foreach(Inventory_Slot slot in current_inventory)

  143.                         {

  144.                                 if (slot.item_id == itemID)

  145.                                 {

  146.                                         if (!slot.Full_Stack())

  147.                                                 return slot;

  148.                                 }

  149.                         }

  150.                 }

  151.                 else

  152.                 {

  153.                         for (int i=current_inventory.Count-1; i>=0; i--)

  154.                         {

  155.                                 Inventory_Slot slot = current_inventory;

  156.                                 if (slot.item_id == itemID)

  157.                                 {

  158.                                         return slot;

  159.                                 }

  160.                         }

  161.                 }



  162.                

  163.                 return null;

  164.         }



  165.         bool Add_New_Slot(int itemID)

  166.         {

  167.                 // add a new stack

  168.                 if (current_inventory.Count < current_limit)

  169.                 {

  170.                         Inventory_Slot newSlot = new Inventory_Slot(itemID);

  171.                         current_inventory.Add(newSlot);

  172.                         return true;

  173.                 }

  174.                 return false;

  175.         }

  176.         public void Sort(Inventory_Type type)

  177.         {

  178.                 Select_Inventory(type);

  179.                 if (null == current_inventory)

  180.                         return;



  181.                 current_inventory.Sort();

  182.         }



  183.         // get the item's amount in inventory

  184.         public int Get_Amount_Item(int itemID, Inventory_Type type)

  185.         {

  186.                 Select_Inventory(type);

  187.                 if (null == current_inventory)

  188.                         return -1;



  189.                 int item_count = 0;

  190.                 for (int i=0; i<current_inventory.Count; i++)

  191.                 {

  192.                         Inventory_Slot slot = current_inventory;

  193.                         if (slot.item_id == itemID)

  194.                         {

  195.                                 item_count += slot.current_stack;

  196.                         }

  197.                 }

  198.                 return item_count;

  199.         }



  200.         // has the item

  201.         public bool Has_Item(int itemID, Inventory_Type type)

  202.         {

  203.                 Select_Inventory(type);

  204.                 if (null == current_inventory)

  205.                         return false;



  206.                 for (int i=0; i<current_inventory.Count; i++)

  207.                 {

  208.                         Inventory_Slot slot = current_inventory;

  209.                         if (slot.item_id == itemID)

  210.                         {

  211.                                 return true;

  212.                         }

  213.                 }

  214.                 return false;

  215.         }



  216.         // check if can create a item

  217.         public bool Can_Create_Item(int recipeID, Inventory_Type type)

  218.         {

  219.                 Item_Profile recipe = Item_Database_Manager.Get_Manager().Get_Item(recipeID);

  220.                 // this item must be a recipe, otherwise, return

  221.                 if (recipe.type != Item_Profile.TYPE.Recipe)

  222.                         return false;

  223.                

  224.                 // check own this recipe, if not, return

  225.                 Select_Inventory(type);

  226.                 if (null == current_inventory)

  227.                         return false;



  228.                 if (!Has_Item(recipeID, type))

  229.                         return false;

  230.                

  231.                 // check what material should be needed, if not enough, return

  232.                 int material_count = recipe.parts.Length;

  233.                 for (int i=0; i<material_count;i++)

  234.                 {

  235.                         Item_Profile.Recipe_Parts recipe_part = recipe.parts;

  236.                         Item_Profile part = recipe_part.part;

  237.                         if (!Has_Item(part.item_id, type))

  238.                                 return false;

  239.                         if (Get_Amount_Item(part.item_id, type) < recipe_part.number)

  240.                                 return false;

  241.                         

  242.                 }

  243.                 return true;

  244.         }



  245.         // create a item base on the recipe.

  246.         public Item_Profile Create_Item(int recipeID, Inventory_Type type)

  247.         {

  248.                 // check if can create a item.

  249.                 if (!Can_Create_Item(recipeID,type))

  250.                         return null;



  251.                 Item_Profile recipe = Item_Database_Manager.Get_Manager().Get_Item(recipeID);



  252.                 // do the create process  

  253.                 if (!Inventory_Manager.Get_Manager().Deposit(recipe.final_product.item_id, type))

  254.                         return null;



  255.                 // withdraw the parts

  256.                 int material_count = recipe.parts.Length;

  257.                 for (int i=0; i<material_count;i++)

  258.                 {

  259.                         Item_Profile.Recipe_Parts recipe_part = recipe.parts;

  260.                         Item_Profile part = recipe_part.part;

  261.                         for (int k=0; k<recipe_part.number ;k++)

  262.                         {

  263.                                 Inventory_Manager.Get_Manager().Withdraw(part.item_id, type);

  264.                         }

  265.                 }



  266.                 // return the item profile

  267.                 return Item_Database_Manager.Get_Manager().Get_Item(recipe.final_product.item_id);



  268.         }



  269. }


  270. Unit_Inventory_Manager
  271. [C#] 纯文本查看 复制代码
  272. using UnityEngine;

  273. using System.Collections;



  274. public class Unit_Inventory_Manager : MonoBehaviour {



  275.         public int itemID; // which item use to test

  276.         public Inventory_Manager.Inventory_Type inventory_type;



  277.         public Item_Profile itemInfo;



  278.         public void Deposit()

  279.         {

  280.                 Inventory_Manager.Get_Manager().Deposit(itemID,inventory_type);

  281.         }



  282.         public void Withdraw()

  283.         {

  284.                 Inventory_Manager.Get_Manager().Withdraw(itemID, inventory_type);

  285.         }



  286.         public void Show_Info()

  287.         {

  288.                 Item_Profile item = Item_Database_Manager.Get_Manager().Get_Item(itemID);

  289.                 itemInfo = item;

  290.         }



  291.         // create a item base on the recipe [move it to the inventory manager]

  292.         public void Create_Item()

  293.         {

  294.                 itemInfo = Inventory_Manager.Get_Manager().Create_Item(itemID, inventory_type);

  295.                 if (itemInfo == null)

  296.                 {

  297.                         Debug.Log("Item create failed!");

  298.                 }

  299.                 else

  300.                 {

  301.                         Debug.Log("Item create successful!");

  302.                 }



  303.         }



  304. }


  305. Unit_Inventory_Manager_Editor
  306. [C#] 纯文本查看 复制代码
  307. using UnityEngine;

  308. using System.Collections;

  309. using UnityEditor;



  310. [CustomEditor(typeof(Unit_Inventory_Manager))]

  311. public class Unit_Inventory_Manager_Editor : Editor

  312. {



  313.         public override void OnInspectorGUI ()

  314.         {

  315.                 Unit_Inventory_Manager manager = target as Unit_Inventory_Manager;

  316.                 //serializedObject.Update();

  317.                 DrawDefaultInspector();



  318.                 //manager.itemID = EditorGUILayout.IntField("item id", manager.itemID);

  319.                 //EditorGUILayout.PropertyField(serializedObject.FindProperty("inventory_type"),true);



  320.                 if(GUILayout.Button("Unit Info"))

  321.                 {

  322.                         manager.Show_Info();

  323.                 }



  324.                 if(GUILayout.Button("Unit Deposit"))

  325.                 {

  326.                         manager.Deposit();

  327.                 }



  328.                 if(GUILayout.Button("Unit Withdraw"))

  329.                 {

  330.                         manager.Withdraw();

  331.                 }



  332.                 if(GUILayout.Button("Create Item"))

  333.                 {

  334.                         manager.Create_Item();

  335.                 }



  336.                 //EditorGUILayout.PropertyField(serializedObject.FindProperty("itemInfo"),true);





  337.                 serializedObject.ApplyModifiedProperties();



  338.         }



  339. }
复制代码

回复

使用道具 举报

ngk02lds78 该用户已被删除
发表于 2014-12-28 02:51:06 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

xbit 该用户已被删除
发表于 2014-12-28 02:51:40 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

woaiwojia6188 该用户已被删除
发表于 2014-12-28 02:52:14 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

0

主题

1232

帖子

3889

积分

vip会员

Rank: 1

积分
3889
发表于 2015-4-9 14:06:03 来自手机 | 显示全部楼层
看帖要回,回帖才健康,在踩踩,楼主辛苦了!
回复 支持 反对

使用道具 举报

天亦有情 该用户已被删除
发表于 2015-4-10 14:08:17 来自手机 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

0

主题

1247

帖子

3904

积分

vip会员

Rank: 1

积分
3904
发表于 2015-4-11 12:42:45 来自手机 | 显示全部楼层
佩服佩服!
回复 支持 反对

使用道具 举报

天使爱上吸血鬼 该用户已被删除
发表于 2015-4-13 21:02:39 来自手机 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

0

主题

1308

帖子

4012

积分

vip会员

Rank: 1

积分
4012
发表于 2015-4-16 00:13:47 来自手机 | 显示全部楼层
楼猪V5啊
回复 支持 反对

使用道具 举报

0

主题

1414

帖子

4080

积分

vip会员

Rank: 1

积分
4080
发表于 2015-4-16 23:25:51 来自手机 | 显示全部楼层
OMG!介是啥东东!!!
回复 支持 反对

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | enginedx注册

本版积分规则

 
 



邮件留言:


 
返回顶部