# Day4(3)

目标:制作一个物品制作系统,首先是UI界面

操作


像这样就行,会有两个界面(主要用到Image,Text,Button),具体操作与库存界面一样

未完待续

后来的补充:教程中需要的合成材料(比如上面的红色晶石)用的英文,名字与预制体名字/拾取物体名字均一致,这样才方便后面根据名字直接实例化预制体。

Day5


目标:

1)解决bug:当同时打开背包和制作菜单后关闭任意一个会导致鼠标光标锁定

2)实现在工具制作界面显示我们已经拥有的材料数量,并保证在可以合成物品的时候才显示制作按钮

3)点击制作按钮后生成对应预制体的同时移除消耗的合成材料(难)

操作


1)在执行锁定光标前检测另一个面板是否在打开状态,若打开着就不锁定光标

2)预制体想要实例化需要把预制体放在更目录的文件夹中

3)当前的画布Canvas中有

  • 准心
  • 显示准心所对物体名字的文本
  • 背包UI(包含多个插槽Image,每个插槽下都有一个Image为显示拥有物品)
  • 制作方向选择UI(包含Button指向工具制作UI,以及指示用图像)
  • 工具制作UI(包含Button指向预制件实例,以及指示用图像)

4)为了方便合成物品创建了BluePrint 蓝图类(BluePrint的代码在后面)

提要:我们根据传入的名字来实例化预制体,根据名字和数量来移除背包内的对应材料,所以将这些参数提前创建蓝图对象,后续只要从蓝图对象上获取数据就可以直接实现添加item到库存系统和从库存系统移除制作物品所消耗的材料

注意:这意味这我们每多一种可以实例化的预制体,就要在CraftingSystem中的Start()内创建新的对应蓝图

图表*2

InventorySystemHaveinventorySreenUI 背包UIslotList 包含所有插槽的列表itemList 包含所有项目/物品对象的列表itemToAdd 将要被添加进背包的物品对象whatSlotToEquip 物品添加的目标插槽isOpen 背包面板已经被打开isFull 背包已经满了/所有插槽都有子元素Awake_f实现单例Start_f初始化PopulateSlotList_f初始化背包插槽的列表AddToInventory_f根据名字添加游戏对象的预制体 包含实例化对象FindNextEmptySlot_f返回下一个空的插槽Update_f检查背包键是否按下 控制背包UI显示和光标锁定CheckIfFull_f遍历查找背包中的空插槽RemoveItem_f根据nameToRemove与amonutToRemove从背包中移除同名的物品ReCalculateList_f更新itemList并去除因为实例化预制体而出现的Clone后缀

CraftingSystemHavecraftingScreenUI 制作方向选择面板/包含工具 药水 等等toolsScreenUI 工具制作面板inventoryItemList 复制InventorySystem.Instance.itemList,在RefreshNeededItems_f中使用toolsBTN 制作方向选择面板的按钮,这个按钮指向进入工具制作面板craftAxeBTN 工具制作面板的按钮,这个按钮指向制作AxeAxeReq1 制作Axe的要求文本1要求文本的数量取决于制作的对象,这里仅为制作Axe要的2个文本AxeReq2 制作Axe的要求文本2isOpen 制作方向选择面板or工具制作面板被打开AxeBLP Axe的蓝图 蓝图是由另一个脚本BluePrint所产生的类Awake_f实现单例Start_f初始化开关状态,按钮,制作要求文本,蓝图 并且建立委托来添加制作的新物品到背包OpenToolsCategory_f开启制作栏的方法CraftAnyItem_f先前在Start中所用的委托,通过蓝图获取制作对象的名字及要求Update_f和InventorySystem中的一样RefreshNeededItems_f检查InventorySystem中各种物品的数量,判断进阶物品是否可以制作,然后显示制作按钮IEnumerator cacilate_f这个方法解决了在一次制作后原材料没有真正减少的问题 使用逻辑不懂 详见代码

public class BluePrint : MonoBehaviour
 {
     public string itemName;
 
     public string req1 = "";
     public string req2 = "";
     public string req3 = "";
     public string req4 = "";
 
     public int req1Amount=0;
     public int req2Amount=0;
     public int req3Amount=0;
     public int req4Amount=0;
 
     public int numOfRequirements;
 
     public BluePrint(string name,int reqNum,string R1,int R1num,string R2,int R2num)//后面可以重载
     {
         itemName = name;
 
         numOfRequirements = reqNum;
 
         req1 = R1;
         req2 = R2;
 
         req1Amount = R1num;
         req2Amount = R2num;
     }
 
 }

Day 6


目标:

  1. 对上次的代码进行一些修改
  2. 新增获取提示界面

操作


修改游戏中的鼠标光标

  • 导入光标图片,设置为Custor类型
  • 在Project Settings -->Player-->Default Custor中添加图片

实现当准心落在在可拾取的物品上时,准心外观改变--> 和当初显示物品文本的逻辑一样,在画布中添加新的图片(手的图片),当检测到物品可拾取就禁用原来的准心,激活新的那个

实现警报装置,在获取东西后屏幕上出现提示,一段时间后自己淡出然后自毁-->在库存系统中添加这三个引用

public GameObject pickupAlert;

public Text pickupName;//拾取对象的名字所要显示的文本对象

public Image pickupImage;//拾取对象的图片所要显示的图片对象

通过方法实现把引用对象内容修改为拾取物品的相关内容,并把这个方法添加到AddToInventory中

对上一次代码的更正:CraftingSystem的RefreshNeededItems()方法不应该在CraftingSystem的update中保持运行,它只需要在有物品添加或移除时候在InventorySystem中的添加或移除方法里调用就好

发现新bug:只要准心瞄准过物品,物品的onTarget就会被修改为真,之后玩家只要在范围内按'E'就可以不用瞄准拾取物品,或许可以在InteractableObject中添加计时器,一旦onTarget为真就开始倒计时,除非一致传入信号,否则很快时间内自动置为false.(不对)

//在InventorySystem中新添的代码
  void TriggerPickupPopUP(string itemName,Sprite itemsprite)
     {
         pickupAlert.SetActive(true);
 
         pickupName.text = itemName;
         pickupImage.sprite = itemsprite;
 
 
     }