【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏10(附项目源码)
本节最终效果演示
文章目录
- 本节最终效果演示
- 系列目录
- 前言
- 快捷栏
- 绘制UI
- 代码控制快捷列表信息
- 源码
- 完结
系列目录
前言
欢迎来到【制作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(); // 刷新制作系统所需物品列表
}
}
}
效果
源码
源码不出意外的话我会放在最后一节
完结
赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注
,以便我第一时间收到反馈,你的每一次支持
都是我不断创作的最大动力。当然如果你发现了文章中存在错误
或者有更好的解决方法
,也欢迎评论私信告诉我哦!
好了,我是向宇
,https://xiangyu.blog.csdn.net
一位在小公司默默奋斗的开发者,出于兴趣爱好,最近开始自学unity,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!php是工作,unity是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~