前言
欢迎来到【制作100个Unity游戏】系列!本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第23篇中,我们将探索如何制作一个类似于七日杀和森林的生存游戏。
本篇内容会比较多,我会分几篇来实现,感兴趣的可以关注一下,以免错过内容更新。
本节主要实现了快捷栏的功能。
快捷栏
绘制UI
绘制快捷栏UI,并且重新绘制背包显示的icon,加入背景用于显示选中效果,记得默认隐藏
记得修改InventorySystem获取图片Icon的方式,以便可以正确显示物品拾取弹窗信息
//添加物品 public void AddToInventory(string itemName) { // 。。。 TriggerPickupPopUp(itemName, itemToAdd.transform.Find("Icon").GetComponent<Image>().sprite); }
代码控制快捷列表信息
public class EquipSystem : MonoBehaviour { public static EquipSystem Instance { get; set; } public GameObject quickSlotsPanel; // 快捷栏面板 public List<GameObject> quickSlotsList = new List<GameObject>(); // 快捷栏列表 private void Awake() { if (Instance == null) { Instance = this; } else { Destroy(gameObject); } } private void Start() { PopulateSlotList(); // 填充快捷栏列表 } private void PopulateSlotList() { foreach (Transform child in quickSlotsPanel.transform) { if (child.CompareTag("QuickSlot")) { quickSlotsList.Add(child.gameObject); } } } public void AddToQuickSlots(GameObject itemToEquip) { // 查找下一个可用的快捷栏格子 GameObject availableSlot = FindNextEmptySlot(); // 将物品放置在该格子内 itemToEquip.transform.SetParent(availableSlot.transform, false); InventorySystem.Instance.ReCalculeList(); // 重新计算物品列表 CraftingSystem.Instance.RefreshNeededItems(); // 刷新制作系统所需物品列表 } //获取空闲的格子 private GameObject FindNextEmptySlot() { // 遍历快捷栏列表,查找是否有空闲的格子 foreach (GameObject slot in quickSlotsList) { if (slot.transform.childCount == 0) { return slot; } } // 如果没有空闲的格子,则返回一个新的GameObject return new GameObject(); } //判断快捷栏是否已满 public bool CheckIfFull() { int counter = 0; // 遍历快捷栏列表,查找是否有空闲的格子 foreach (GameObject slot in quickSlotsList) { if (slot.transform.childCount > 0) { counter ++; } } // 如果遍历完所有格子,都没有空闲的格子,则表示快捷栏已满 if (counter == 7) { return true; } else { return false; } } }
挂载代码,配置信息
修改InventoryItem,实现特定物品才可以拉到快捷栏
[Header("是否已经装备")] public bool isNowEquipped; // 当鼠标点击物品时触发 public void OnPointerDown(PointerEventData eventData) { // 。。。 //按左shift再点击鼠标左键装备/卸载物品 if (Input.GetKey(KeyCode.LeftShift) && eventData.button == PointerEventData.InputButton.Left) { // 该物品可装备尚未装备,并且装备栏未满 if (isNowEquipped == false && EquipSystem.Instance.CheckIfFull() == false) // if (isEquippable && isNowEquipped == false && EquipSystem.Instance.CheckIfFull() == false) { // 将物品添加到快捷栏并标记为已装备 EquipSystem.Instance.AddToQuickSlots(gameObject); isNowEquipped = true; } // 该物品可装备已经装备,并且背包未满 else if (isNowEquipped == true && InventorySystem.Instance.CheckIfFull() == false) { // 将物品添加到背包并标记为未装备 InventorySystem.Instance.AddToInventory(gameObject); isNowEquipped = false; } } }
修改InventorySystem,添加新的新增物品方法
//添加物品 public void AddToInventory(GameObject itemToAdd) { // 找到下一个空闲的槽位 whatSlotToEquip = FindNextEmptySlot(); // 将新实例化的物体的父对象设置为whatSlotToEquip itemToAdd.transform.SetParent(whatSlotToEquip.transform, false); // 将物品名称添加到itemList中 itemList.Add(itemToAdd.GetComponent<InventoryItem>().thisName); ReCalculeList(); CraftingSystem.Instance.RefreshNeededItems(); }
修改ItemSlot,判断放置时是否是快捷栏,修改装备状态
// 当拖拽物体被放置到当前物品槽时 public void OnDrop(PointerEventData eventData) { if (!Item) { // 。。。 // 如果当前物品槽不是快捷栏 if (transform.CompareTag("QuickSlot") == false) { // 标记待装备的物品为未装备状态 DragDrop.itemBeingDragged.GetComponent<InventoryItem>().isNowEquipped = false; InventorySystem.Instance.ReCalculeList(); // 重新计算物品列表 CraftingSystem.Instance.RefreshNeededItems(); // 刷新制作系统所需物品列表 } else { // 标记待装备的物品为装备状态 DragDrop.itemBeingDragged.GetComponent<InventoryItem>().isNowEquipped = true; InventorySystem.Instance.ReCalculeList(); // 重新计算物品列表 CraftingSystem.Instance.RefreshNeededItems(); // 刷新制作系统所需物品列表 } } }
效果
源码
源码不出意外的话我会放在最后一节