系列文章目录
迷失岛游戏框架开发个人每集总结(第一期)
迷失岛游戏框架开发个人每集总结(第二期)
前言
在上一期中,我们实现通过鼠标点击带有“item”标签的物体后,取消该物体的显示,获取该物品的名称,并将其储存到类型为itemname的列表itemList中。
这次要实现的是讲鼠标点击后的图片传入到UI里的(image)slot中,使刚被点击的物体能在UI中显示,并且在鼠标触碰到slot时,显示当时slot显示的图片的名称。以及能够实现点击UI中的左右按钮是能产生效果 。
1代码
1.1
InventoryUI
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//用于使用ui
public class InventoryUI : MonoBehaviour
{
public Button leftButton, rightButton;
public SlotUI slotUI;
public int currentIndex;//显示UI当前序号,如果是第一个物品的序号,则左按键不可动,
//如果是最后一个物品的序号则右按键不可动,无物品则两个按键都不可动
private void OnEnable()
{
EventHandler.updateUIEvent += OnUpdateUIEvent;//订阅OnUpdateUIEvent这个事件
}
private void OnDisable()
{
EventHandler.updateUIEvent -= OnUpdateUIEvent;
}
private void OnUpdateUIEvent(ItemDetails itemDetails ,int index)
{
if (itemDetails == null)//物品信息为空
{
slotUI.SetEmpty();
currentIndex = -1;
leftButton.interactable = false;
rightButton.interactable = false;
}
else
{
currentIndex = index;
slotUI.SetItem(itemDetails);
}
}
}
1.2
SlotUI
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class SlotUI : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler//接口
{
public Image itemImage;
public ItemTooltip tooltip;
private ItemDetails currentItem;//储存当前的物品信息
private bool isSelected; //实现点击了slotUI后确定该物品被选中了(因为玩家要使用UI里的道具)
public void SetItem(ItemDetails itemDetails)//用于显示slot应该是什么物品图片
{
currentItem = itemDetails;
this.gameObject.SetActive(true);
itemImage.sprite = itemDetails.itemSprite;
itemImage.SetNativeSize();
}
public void SetEmpty()//一开始背包里没有物体,隐藏物体
{
this.gameObject.SetActive(false);
isSelected = false;
}
}
为什么取名交slotUI
slotUI 是一个游戏开发中常见的术语,通常指代在游戏界面中用于显示和管理物品槽(Inventory Slot)的
用户界面元素(User Interface)。
物品槽是指玩家的背包、物品栏、装备栏等部分,这些部分通常由一系列的格子组成,用于存放、管理、拖放
不同类别的游戏物品。
而 slotUI 则是针对这些物品槽设计的一种 UI 界面,主要目的是在游戏中方便玩家管理自己的物品,提供更好的
可视化交互体验。
slotUI 的具体实现通常有多种方式,可以是简单的用纹理图片模拟物品槽,也可以是更为复杂的使用 Unity 引擎
的 UI 系统制作可交互的物品槽。
在实现 slotUI 的过程中,需要考虑到物品槽的大小、排列方式、放置限制等因素,以及与游戏系统的逻辑关联,以确保游戏体验的稳定性和流畅性。
方法setItem的解释
传递物品的名字然后返回itemDetails然后传给UI,让UI能显示
currentItem = itemDetails; 这行代码将传入的物品详细信息(ItemDetails)赋值给当前物品(currentItem)。
this.gameObject.SetActive(true); 这行代码将该脚本所在的游戏对象(gameObject)设为激活状态,
以便在游戏中显示该物品。
itemImage.sprite = itemDetails.itemSprite; 这行代码将物品详细信息中的物品图片(itemSprite)
赋值给UI中的物品图片(itemImage.sprite)。
itemImage.SetNativeSize(); 这行代码将UI中的物品图片按照原始尺寸设置大小,以确保物品图片显示的正确性。
1.3
创建一个事件中心,把数据通过事件订阅来传递给各个订阅了该事件的方法。
EventHandler
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class EventHandler : MonoBehaviour
{ //可以把需要读这些数据的代码都订阅到这个事件里面来,同时也需要呼叫
//把数据通过订阅的方式来传递到各个代码当中去执行各自的函数方法
public static event Action<ItemDetails, int> updateUIEvent;
//呼叫(触发)该事件获取数据,并且订阅了该事件的代码会执行各自的方法
public static void CallUpdateUIEvent(ItemDetails itemDetails,int index)
{
updateUIEvent?.Invoke(itemDetails, index);
}
}
什么是呼叫
在 Unity 中,呼叫指的是调用或触发事件中注册的委托或函数的过程。在 Unity 的事件系统中,常常会使用 UnityEvent 类型来定义和管理事件。通过将需要执行的委托或函数注册到 UnityEvent 实例中,当该事件被触发时,就会依次对注册的委托或函数进行呼叫(即调用)。
public static event Action<ItemDetails, int> updateUIEvent;
这行代码定义了一个名为updateUIEvent的静态事件,事件类型为Action<ItemDetails, int>,
即携带两个参数,分别是物品详细信息(ItemDetails)和索引(int)。
其他代码可以通过订阅这个事件来获取这些参数。
public static void CallUpdateUIEvent(ItemDetails itemDetails,int index)
这行代码定义了一个名为CallUpdateUIEvent的静态方法,用于在其他代码中调用updateUIEvent事件,
并传递两个参数:物品详细信息(itemDetails)和索引(index)。
总体来说,这段代码的作用是定义了一个事件和一个方法,
用于在不同的代码模块之间传递物品详细信息和索引,以便实现不同模块之间的数据交互。
其他代码可以通过订阅事件或调用方法来获取这些数据。
1.4
InventoryManager
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//单例模式
public class IventoryManager :Singleton<IventoryManager>//单例模式
{
public ItemDataList itemData;
//创建一个数据的类型来储存我当前所持有的物品
[SerializeField] private List<ItemName> itemList = new List<ItemName>();
//实现一个添加物品的方法,传进物品的名字
public void AddItem(ItemName itemName)
{
if(!itemList.Contains(itemName))
{
itemList.Add(itemName);
//UI对应显示
EventHandler.CallUpdateUIEvent(itemData.GetItemDetails(itemName), itemList.Count - 1);
//呼叫事件调用
}
}
private int GetItemIndex(ItemName itemName)
{
for(int i=0;i<itemList.Count;i++)
{
if (itemList[i] == itemName)
return i;
}
return -1;
}
}
2 总结
主要是为了厘清代码思路,主要是没有接触过事件订阅,刚开始很懵,现在多看几遍后就有些明白了。