系列文章目录
前言
在上一期,我们实现通过点击箭头处的物体,通过它的碰撞体,识别出该物体的tag,找出对应物体所挂载的脚本并且调用脚本里的切换场景方法,实现场景的切换。
主要记录的是代码的部分
在这一期学习最基本物品管理系统,实现点击场景中的物品,将其添加到我们的工具栏中,然后会记录我们有哪些工具,并且可以点击使用。
1
1.1
要为我们所要点击的物体添加碰撞体并添加“item”标签。
//Cursor Manager里的
private void ClickAction(GameObject clickObject)
{
switch(clickObject.tag)
{
case "Teleport":
var teleport = clickObject.GetComponent<Teleport>();
teleport?.TeleportToScene();
break;
//调用这个带有“item”标签的物体的公开方法,将物品添加到背包当中
case "Item":
var item = clickObject.GetComponent<Item>();
item?.ItemClicked();
break;
}
}
管理物品的加载
1.2
//用来写所有的枚举变量、
脚本:Enum
//item脚本需要物品的名字,通过判断物品的名字匹配对应的互动方法从而实现不同的互动。
//使用枚举来罗列物体有什么名字(为了方便)
public enum ItemName
{
None,Key,Ticket
}
1.3
脚本:Item
using System.Collections.Generic;
using UnityEngine;
public class Item : MonoBehaviour
{
//物品名字,通过传递物品名称数据用来匹配互动
public ItemName itemName;//ItemName是枚举类型,在引擎中可为挂载了该脚本的物体通过下拉菜单选择物品类型
//点击物品之后需要实现后续的互动
public void ItemClicked()
{ //添加到背包后隐藏场景里的物体
IventoryManager.Instance.AddItem(itemName);//调用该方法将物体添加到背包
this.gameObject.SetActive(false);//挂载了该脚本的物体会隐藏
}
}
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);
//TODO:UI对应显示
EventHandler.CallUpdateUIEvent(itemData.GetItemDetails(itemName), itemList.Count - 1);
}
}
}
[SerializeField]的作用
SerializeField是Unity中的一个特殊标记,用于将一个私有变量序列化,使其可以在Inspector视图中显示和编辑。(需要注意的是,SerializeField只能序列化非静态的私有变量,而且不能序列化方法或事件等。此外,在构造函数中初始化的变量无法使用SerializeField进行序列化。)
1.5
脚本:ItemDataList
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//用于保存所有的物体
[CreateAssetMenu(fileName ="ItemDataList",menuName ="Inventory/ItemDataList")]
public class ItemDataList : ScriptableObject
{
//ItemDetails类型的List
public List<ItemDetails> itemDetailsList;
/**
* 这段代码定义了一个公共函数GetItemDetails,其返回类型为ItemDetails,这样就可以获得该类所包含的item的图片,接受一个参数itemName,类型为ItemName。函数的实现过程如下:
调用itemDetailsList的Find方法,该方法会在itemDetailsList中查找第一个满足指定条件的元素,并返回该元素。
Find方法中使用了一个Lambda表达式,i => i.itemName == itemName,该表达式定义了一个匿名函数,
表示对于itemDetailsList中的每个元素i,当i的itemName属性等于函数的参数itemName时,返回true,否则返回false。
因此,最终的结果是返回itemDetailsList中第一个满足itemName属性等于函数参数的元素的详细信息(即ItemDetails对象)。
该函数的作用是获取指定itemName的物品详细信息,可以说是一个查询函数。其中,itemDetailsList是一个列表,
存储了所有物品的详细信息,而ItemDetails是一个自定义的类,用于描述物品的详细信息,包括物品的名称、描述、图标等属性。
8在实现物品系统时,通常会用这样的方式来存储和查询物品的详细信息。
* */
public ItemDetails GetItemDetails (ItemName itemName)
{
return itemDetailsList.Find(i => i.itemName == itemName);
}
}
[System.Serializable]
public class ItemDetails
{
public ItemName itemName;
public Sprite itemSprite;
}
(AI给出的,不一定正确)
[CreateAssetMenu(fileName =“ItemDataList”,menuName =“Inventory/ItemDataList”)] 是Unity的一个特殊标记,用于创建自定义资源菜单项。
在这个例子中,它的作用是为一个名为ItemDataList的自定义资源添加了一个“Inventory”菜单选项,用户可以在这个菜单下方快速创建一个新的ItemDataList资源。其中,fileName参数指定了创建的资源文件名,menuName参数则指定了资源菜单项的路径和名称。
[System.Serializable]是Unity的一个特殊标记,用于将一个类或结构体标记为可序列化。它的作用是让Unity可以在场景或资源中序列化该类或结构体的实例,并在需要时将其保存到文件中或从文件中加载。
当一个类或结构体被[System.Serializable]标记时,它的成员变量也会被标记为可序列化。这意味着它们可以被保存到文件中并在需要时进行加载,而无需手动编写序列化代码。
最后
这一期的视频比较短,也相对简单,就不多赘述。