Inventory背包学习
(资料图片)
制作背包基本UI
基础的panel,container
SlotHolder【包含ItemSlot <- amount】保存为prefab
创建在地图上的物品ItemOnWorld,装备在身上的物品ItemEquipment
ItemData_SO,用于保存item数据【name,icon,stackable可堆叠,描述等等信息】
ItemType(Useable,Weapon,Armor等等)
name
icon
prefab_EQ
ItemPickUp【碰撞到玩家之后销毁自己,给玩家加入背包】
调用InventoryData_SO中的AddItem给某个背包添加物品,RefreshUI();
删除本体
Equipment
ChangetWeapon
EquipWeapon
UnEquipWeapon
需要的话可以修改attackData
InventoryManger
需要获取的变量:
InventoryData
Container
UI Panel
ItemToolTip
Canvas(inventoryCanvas , dragCanvas)
DragData【自定义类,包含originalHolder,originalParent】
Fnc
获取模板数据
保存、读取数据
开关背包的bool
Check DragItem is In SlotArea 检查拖拽物品是否在某一个Slot范围内
创建背包的数据库Inventory Data【每一个背包都对应一个inventoryData】
InventoryItem【这是背包里面的物品类型,储存itemData和amount】
Listitems; 列表中的每一个元素都对应背包中对应序号的物品,交换之后会交换列表中的位置
AddItem(ItemData_SO , Int)
可堆叠
在列表中寻找物品,有则堆叠上去
不可堆叠、没有找到相同物品
在第一个空位置添加相应物品
InventoryUI 背包显示物品对应图标
ContainerUI 保存该背包下的所有SlotHolder
RefreshUI(),更新每一个itemUI的index ,index有值之后就可以UpdateItem了
SlotHolder
单元格类型SlotType
获取自身子类itemUI
UpdateItem,将自身单元格的item更新到itemUI上
switch更换对应类型的数据库
进行对应的操作,比如说装备武器
更新UI的显示
ItemUI(包含Image <- text)具体每个物体UI上,控制image,text显示
SetUpItemUI
如果当前格子有物品,则更新icon、amount、SetAction(true);
如果没有物品,SetActive(false);
InventoryData_SO InventoryData ,int index 保存这个地方对应哪一个数据库的哪一个index
创建其他Panel,按照上面的方式,保存itemUI成为Prefab,设置好SlotType,创建对应的数据库
DragItem 实现拖拽物品(实际上是拖拽的ItemUI),添加到可以拖拽的背包格子(ItemUI)上,命名空间EventSystems
接口:IBeginDragHandler, IDragHandler ,IEndDragHandler,拖拽开始、拖拽中、拖拽结束
/cn/current/ScriptReference/ 接口的代码手册
PointerEventData eventData(position鼠标位置,pointerEnter鼠标进入某个区域(triggerEnter))
OnIBeginDragHandler
记录原始信息
设置父级为DragCanvas
OnIDragHandler(自带Update)
跟随鼠标位置移动
OnIEndDragHandler
放下物品,交换数据
() 【具有给定ID的指针是否位于EventSystem对象上】
在InventoryManager里面创建CheckInInventoryUI(vec3)检测拖拽物品是否在某一个slot范围内
循环若干个containerUI需要检测每一个该检测的)
(方形范围 , position)) 判断position是否在方格范围内
检查鼠标指向的位置是否有SlotHolder组件 ,设置为targetHolder。如果image显示出来了,获取不到SlotHolder,则要去image的父级获取
交换物品,判断targetHolder是否为空,是否不是原始Holder,需要判断targetHolder的slotType能否进行交换,调用SwapItem()
交换完毕后更新currentHolder,targetHolder
修改父级回到原始
修改RectTransform回到原始设置
offSetMax锚点右上偏移
offSetMin锚点左下偏移
[RequireComponent(typeof(ItemUI))]在拖拽物品上自动添加ItemUI
添加一个最高层的DragCanvas,在拖拽时加入此Canvas,保证拖拽不会被挡道其他UI后面,在InventoryManager里面保存
InventoryManger中创建一个类DragData
保存原始的Holder,原始的Parent(RectTransform)
用来临时储存拖拽信息,使用的时候new一个新值
SwapItem() 【修改数据列表的排列】
targetItem,tempItem【指向当前item,如果交换过去则清空】
判断是否堆叠,可堆叠则堆叠,否则直接交换
Useable Item可使用物品(双击使用)
创建对应的数据,物品
在SlotHolder中,利用 IPointerClickHandler 接口实现双击使用物品
代码手册:/cn/current/ScriptReference/
判断点击次数为偶数,避免多次点击不为2会失效
UseItem(),判断是否为空,是否可使用,数量是否大于0
链接到Character组件实现改变属性
开关Panel,InventoryManager里面设置一个bool,一个func,用于判定打开背包时人物不可移动
ActionButton
public KeyCode actionKey,进行逐一设置
背包中实现实时投影玩家
摄像机输出到Render Texture
UI创建Raw Image接收这个Render Texture即可
ItemToolTip物品信息显示栏
创建UI,主要用到Content Size Fitter 和 Layout Group
脚本ItemToolTip
SetUpToolTip(ItemData_SO itemData),设置图标、名称、描述等,配合UI显示
Update中跟随鼠标的位置,并且根据条件判断应该在鼠标的哪个方向显示,获取矩形四个角顶点位置(世界坐标)
12
03
在SlotHolder中 添加 IPointerEnterHandler ,IPointerExitHandler两个接口
鼠标进入时如果有物品,则更新ToolTip并且显示
离开时、SlotHolder(背包)关闭时取消ToolTip的显示
Loot Item 掉落物品
LootSpawner脚本
创建一个序列化的类,包含item以及一个权重(设置掉落概率)
SpwanLoot
获取一个随机值,从lootItems数组中遍历,寻找符合概率的物品,如果掉落之后break则只掉落一个物品
背包数据的保存与读取
调用SaveManager,在背包内物品有所更改、或是别的条件下进行保存数据
DragPanel面板的拖拽,调整Hierarchy排序方式改变渲染层级
拖动时,为了避免电脑分辨率和Canvas分辨率不同,所以拖动要除以Canvas的分辨率
+= / ;
IPointerDownHandler
渲染层级: / Get...
滚轮选择ActionBar物品【实现时需要对前文的设置进行修改以达到最好的效果,属于两种截然不同的背包方法】
InventoryManager 中 ("Mouse ScrollWheel")检测滚轮输入 上为正,下为负
在SlotHolder中添加index来进行索引,添加选择框的image
InventoryManager 中 添加选择currentSelectHolder的函数
更新前取消选择框iamge,更新后显示选择框image
选择时装备物品,如果是空栏则卸载物品