系列文章目录
麦田物语第十天
文章目录
一、背包UI显示
本小节用于实现Inventory的UI和数据之间的连接。
首先创建Scripts->Inventory->UI->InventoryUI脚本,并将其挂载到UI场景中的Main Canvas画布下面的Inventory空物体上。
那么接下来就到了编写连接代码的环节。
首先,InventoryUI属于命名空间MFarm.Inventory,上一届的SlotUI也属于这个命名空间下。
接着就是一些变量的声明,在InventoryUI脚本中我们想要实现对Slot_UI的显示控制,因此我们需要声明一个数组,并在Unity界面中将Inventory下的所有Slot_UI拖拽到该数组中。(拖拽顺序也有讲究,因为我们希望操作栏中的UI可以显示先拾取的物品,如果太多的话就会装入背包中,那么首先将ActionBar中的Slot_UI先拖拽,后将Player Bag中的Slot_UI拖拽进去即可)。
由此可以得出我们背包的总容量是26,那么我们存储背包数据的ItemList大小也应该为26,因此我们需要更改PlayerBag_SO的背包的Item List的大小为26。
接下来我们的SO文件中数据怎么对应每一个Slot_UI,就需要在每一个Slot_UI身上挂载的脚本中增加变量slotIndex,并且在InventoryUI的Start方法中对其进行赋值。
那么我们然后需要考虑的东西就是怎么把数据和UI进行连接,当我们拾取物品时,会调用AddItem方法,从而将数据添加进PlayerBag_SO文件中,那么我们可以在这个方法中更新UI。
这个游戏比较大,例如我们可以做一个箱子去存储物品,那么我们更新UI时需要考虑进行那部分UI的更新,所以此时需要一个枚举类型(Enums脚本中编写)
枚举类型代码如下:
public enum InventoryLocation
{
Player,Box
}
接下来就可以进行更新UI了,我们希望在InventoryManager在添加物品的调用的时候造成数据更改,物品位置更改时更新一下对应的UI,这次我不希望使用单例模式去叫(调用)Inventory的UI,这样会造成很多的牵连。此时我们需要使用在这个项目中第二个使用的结构:创建一个事件中心,每次我呼叫这个事件,所有注册到这个事件里面的函数都会被执行。《Action》
接下来我们创建Scripts->Utilities->EventHandler脚本,我们使用这个脚本来控制所有的事件,这个脚本不用继承自Mono,并且我们想要这个脚本随时被调用,因此将这个脚本编写为静态的(static)
关于静态和非静态的区别,大致为静态类属于整个类加载器,而非静态类属于单个实例。 这意味着静态类的生命周期与类加载器的生命周期相同,而非静态类的生命周期与其实例的创建和销毁有关。
在这个脚本中我们先写第一个方法,在Action中我们要知道更新那个位置的UI(背包还是箱子),同时还要知道对应的数据(背包中的数据),此时就完成了注册,接着我们在下面就直接进行呼叫从而Invoke
EventHandler代码如下:
public static class EventHandler
{
public static event Action<InventoryLocation, List<InventoryItem>> UpdateInventoryUI;
public static void CallUpdateInventoryUI(InventoryLocation location,List<InventoryItem> list)
{
//先判断UpdateInventoryUI是否为空,再Invoke
UpdateInventoryUI?.Invoke(location, list);
}
}
上述我们注册事件和调用事件都写好了,那么应该怎么去使用呢?
首先我们需要在InventoryUI中去注册这个时间,Unity有自带的方法OnEnable和OnDisable,添加事件后自动生成函数方法即可;在此处我们将InventoryUI的注册和删除方法单独列出:
private void OnEnable()
{
E