【Unity】背包系统 + 物品管理窗口 (上)

物品窗口管理(ItemEditor) --------- 上

简介

Unity

Unity是一款非常强大的游戏引擎,相比于虚幻个人认为Unity游戏引擎相对来说会更加的简单,Unity兼顾跨平台以及各类的游戏开发,国内专属的团结引擎还有专属于国内特有的小程序开发。

背包

在游戏开发中背包是一个非常关键的部分我们开发像沙盒游戏,RPG游戏,甚至很多银河恶魔城类的游戏都需要背包来存储数据,其实我认为称作背包其实不准确,应该称作存储系统才对,因为我们这个都是用来存储数据罢了,不管是什么只要需要存储一类东西都是可以用这套系统的!那么我们正式开始


实现

当然了,在这之前我们需要先创建一个项目名字就叫做StockpileSystem存储系统,我希望在我完成好这个项目之后把这个StockpileSysytem打包成一个包,方便我之后的所有项目都能使用这个存储系统,然后再根据这个项目的特性修改这个包,OK仔细看一下下面这个我们将会实现以下功能:

  • 物品表
  • 物品存储

OK那么我们也废话不多说直接开始!!!

Item类

首先我们需要一个背包存储的基本元素,也就是你的背包需要存储什么东西,有些人的游戏不同所需存储的东西内容自然也是不相同的,我们开发游戏时我们物品最常有也是基本必须的属性就是名字和ID

javascript 复制代码
public class ItemBase
{
	public int ItemID; // 物品ID
	public string ItemName; // 物品名称
}

当然大家可以添加一些自己需要或是想要的属性,比如说如果你的Item还有许多种类型那么你就可以再定义一个ItemType的枚举,如果你不需要那就不用再写,我们这边的情景是:冒险探险的沙盒游戏,那么我们编写一下我们的ItemType:

javascript 复制代码
public enum ItemType
{
	Weapon,   // 武器
	Food,     // 食物
	Medicine, // 药水
	Clothes,  // 衣服
	Resources,// 资源
}

当然大家这个自己根据自己的情况进行编写好吧,我这边只是给出一个情景,那么我们再完善一下我们的ItemBase类

javascript 复制代码
namespace StockpileSystem
{
	[System.Serializable] // 序列化
	public class ItemBase
	{
		public int ItemID;			// 物品ID
		public string ItemName;     // 物品名称
		public ItemType Type;       // 物品类型
		public Sprite ItemIcon;     // 物品Icon
		public Sprite ItemOnWorld;  // 物品世界图标
	}
}

首先我们序列化了我们的ItemBase类使其能够再Unity编辑器种渲染出来,方便我们进行编辑,接着我们定义了一些ItemBase的基本变量包括物品的ID,名称,类型,图片,这里我主要为了节省代码量,大伙需要其他属性,比如攻击力的大小,防御力的大小,药水的增益效果大家伙都自己表示一下就可以啦!

物品ID

通常我们使用:
ID:XXXX

上面这种情况适用于大家创建的独立游戏能够使用1000-9999表示的情况下

我们大多数的ID都是这样的,极个别需要五位数才能表示完的游戏其实时少数,四位数其实对于独立游戏开发者已经是非常合适的了,当然了如果大家非要使用

  • ID:1000

  • ID:1001

  • ID:1002

  • ID:1003

    ...

物品属性

当你Item需要一些特殊属性时,比如攻击力,以及一些增益效果,当然了药水并没有攻击力,那么这个时候我们该怎么办呢?

很简单我们只需要将他的攻击力标记为-1那么我们在判断时我们就可以知道这个东西并没有攻击力,那么其他的东西也是同理的

代码:

我们展示一下这部分的代码:

javascript 复制代码
using UnityEngine;

namespace StockpileSystem
{
    public enum ItemType
    {
	    Weapon,   // 武器
	    Food,     // 食物
	    Medicine, // 药水
	    Clothes,  // 衣服
	    Resources,// 资源
    }
	[System.Serializable] // 序列化
	public class ItemBase
	{
		public int ItemID;			// 物品ID
		public string ItemName;     // 物品名称
		public ItemType Type;       // 物品类型
		public Sprite ItemIcon;     // 物品Icon
		public Sprite ItemOnWorld;  // 物品世界图标
	}
}
ItemTable类

我们已经完成了ItemBase类的编写,但是ItemBase类存储的是一个物品的信息,那么当然了我们不可能只创建一个Item,大多数独立游戏都不会有太少的,所以我们需要一个ItemTable用来存储我们这个游戏中的所有Item,那么我们存储使用的数据结构也没有那么难其实大部分都是顺序表,再通过ID的查询就可以实现这个类,但是我们还需要编辑这个类,因此我们需要Unity自带的存储结构:ScriptObject

代码实现

javascript 复制代码
using System.Collections.Generic;
using UnityEngine;
namespace StockpileSystem
{
    [CreateAssetMenu(fileName = "ItemTable", menuName = "Items/New ItemTable")]
    public class ItemTable : ScriptableObject
    {
        public List<ItemBase> ItemDetails;
    }
}

代码很简单相信大家也都能看得懂,就是创建一个列表存储所有的ItemBase,那么我们在Unity编辑完这个代码后相信大家的Unity编辑器是这样的:

大家可以看到我创建了一个Data文件夹准备用来存储数据,那么我该怎么做呢?当我们写完ScriptObject的ItemTable时我们就可以创建一个文件,首先我们在Data文件夹下再创建一个Items文件夹,并右键创建一个ItemTable文件如下所示:

那么我们直接创建它,名字可以取"数据库',"物品信息库",等等都可以,这里我还是以"物品表"作为我的文件名称,当我们创建好了之后,并再列表中创建一个Item就可以看到以下画面

到了现在大家就可以开始创建编辑自己的物品表了,当然了大家伙可以能会觉得我们的编辑界面不适合以后长期开发不美观也不支持预览Icon,包括大家如果是团队开发的话大家的团队里有人不懂代码,那这时候我们最好是创建一个图形化编辑页面来协同开发,这时候我这里给大家提供一个Unity超级强大的UI编辑工具:UI Toolkit

Item Editor UI界面(可选择操作):

最终实现效果:
实现:
创建文件;

这个是我们这篇文章最核心的部分使用Unity的UI Toolkit创建一个编辑窗口:

我们为什么要创建一个这样的窗口呢?,不仅仅是因为我们需要可持续的进行开发的话,一个好的界面和优秀的开发结构都是我们开发下去的动力,那么我们该如何实现呢?首先第一步肯定是先创建一个Editor文件夹来存放我们的编辑器的存储内容,在Unity中Editor文件夹是不会在打包中打包的那么我们就在Editor文件夹下创建我们的代码文件,然后我还要额外创建一个文件夹来存放我的照片,当然这个照片只存放我的Logo

其中Image文件夹会存放一个Defalut Icon我们开始吧,首先我们右键Editor文件夹,在UI Toolkit创建一个Editor文件请看下图

这里我们直接点击这个按钮,他会弹出一个窗口,我们取名为ItemEditor,并点击确定,请看下图

编辑UI界面
调整代码

现在我们已经创建了一UI的界面了相信大家的Unity界面也弹出来了,但是它只显示几行字母但是我们希望创建一个具有编辑能力的可视化Item编辑页面,但是在这之前我们得先了解一下如何使用这个UI界面,不得不说Unity当之无愧游戏引擎的扛把子,功能太强大了。我们看回我们的Editor窗口:

这个时候我们可以看到有三个页面首先我们先进入第一个文件夹把代码调整成我的代码样式:

javascript 复制代码
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public class ItemEditor : EditorWindow
{
    [SerializeField]
    private VisualTreeAsset m_VisualTreeAsset = default;

    [MenuItem("Stockpile/ItemEditor")] // 自定义窗口位置
    public static void ShowExample()
    {
        ItemEditor wnd = GetWindow<ItemEditor>();
        wnd.titleContent = new GUIContent("ItemEditor");
    }

    public void CreateGUI()
    {
        // Each editor window contains a root VisualElement object
        VisualElement root = rootVisualElement;
		// 删除初始化Label
        VisualElement labelFromUXML = m_VisualTreeAsset.Instantiate();
        root.Add(labelFromUXML);
    }
}

这里我在我标有中文注释的地方做了修改,首先我删除了他在初始化时自动创建的Label文本文件也就是我们在开始窗口的地方又看到一个什么什么C#的字体,那个就是初始化创建的字体文件,大家如果懒得找的化可以直接复制我的代码,但是我先声明一下我的Unity版本是22.3.53的版本,高版本或者低版本的初始代码有可能跟我不一样但是没事这个无关紧要大家找到类似的代码删除即可!,那么我们修改的二个位置就是修改我们Unity编辑器中窗口的位置,我们看下图即可

点击这个就可以打开我们的窗口,当然了我们的文字是可以自己拟定的大家随便取自己喜欢的名字就可;

编辑窗口UI

这个时候我们双击打开第三个文件,我们可以很清楚的看到这个界面的UI界面,我们可以看到最开始的那个C#的字样消失了,因为我们上一步就给他处理掉了,那么接下来:
我演示的过程只是一个样例大家想要其实可以编辑UI界面更美观,更优雅的,但是,如果大家还不是很懂一旁组件库中的组件有啥用的时候我还是很推荐你跟着我们一起走一遍再去编辑自己想要的窗口的,至于链接部分我们先别急,我们先把美美的窗口写出来之后,再去写我们连接数据部分的代码
我们正式开始!!!


第一步:删除初始化Label,创建基本框架

现在大家的屏幕上有两行Label文件我们先删除掉,很简单大家只需要右键删除即可,就像我下面这样

删掉之后我们再进行窗口的初始化,首先我们想实现的是左边有一个列表能列出我们的所有的Item,那么右边显示我们选中Item的详细信息,我们在预览部分已经给大家展示了,首先我们先单击ItemEditor.uxml调整一下窗口的大小, 然后将一个Visual Element 拖拽到根目录下取名叫做Main如下所示


OK我们完成了第一步的第一小步,接下来毕竟要创建两部分那么我们接着在Main的下方再次拖拽两个VisualElement,一个Visual Element名字就取做ItemList,另一个就叫做ItemDetails如下图所示

但是这个不符合我们想要的效果我们想要的是左右排列的格式,这个时候我们该怎么办呢?很简单我们单击一下我们的Main的VisualElement然后我们会在UI 编辑器的左上角看见编辑选项我们将点击第一个按钮即可其调整为纵向排列后面的按钮都会相应的变为纵向模式。

这个时候我们会发现:欸!变了欸!他变成横向排列了!

但是我们发现我们左边这个东东太大了,我们需要把他变小一点,而且必须能让他和窗口一起协同变小,也就是他会根据窗口的缩放来变换大小,那么我们就需要用到比例了,我们设置左边窗口的ItemEditor的窗口的永远为这个窗口的30%那么问题就解决了,那么我们该怎么做呢?没关系我们一步步来
首先我们将 ItemList 的 Flex属性修改为以下内容

因为我们的ItemList是从上到下的所以我们选择纵向排列,并把延伸设为0那么我们在Itemdetails中我们也设置相对应的操作,同样是一样的设置。
其次我们设置以下比列

这个是ItemList

那么我们将ItemDetails的Size再设置一下就OK了

ItemList部分内容

OK了搞定了这样我们就把框架搞出来了那么我们我们接下来的任务也就是先把ItemList的标头弄出来,首先我们希望我们ItemList能有一个表头让其能够实现有一个文字Title和一个按钮用来添加元素,其次就是下面能够有一个列表来滑动我们的ItemList那么我们来搞一下吧!
首先分别拖拽VisualElement和ListView到ItemList的图中并分别做出如下设置



Header相关设置

这里我们调整了Margin:距离边界的距离以及缩放以及位置,打击详细了解的
ItemList相关设置

OK了我们完成了第一步的设置我们接下来该怎么办呢?那么这个时候就该设置我们的标题了,这个时候我们先在Header下面拖拽Label作为Tietle,在拖拽一个按钮上去,我们再做修改,效果如图。

这时我们再稍作修改代码就OK啦!我展示一下我的修改内容,大家伙可以根据自己的需求在稍作调整
文本相关设置


按钮相关设置

OK效果展示:

那么我们已经完成了ItemList部分的内容了,那么接下来我们创建ItemDetails部分的内容吧!

ItemDetails部分内容

那么我们的详情页面就包括一张图片姓名和ID和一些属性,那么我们就分为上下两部分,上面部分又分为左右两个部分,并且分为Icon和姓名与ID,我们废话不多说直接开搞!
以下部分子物体全部都为VisualElement

那么接下来我们调整一下我们的相关设置那么开始吧首先我们将每个子物体的VisualElement属性的延展设置为0如下图所示
每个子物体!!!,然后呢我们在将Header设置为标题+按钮的形式(此处为ItemDetails的子物体)

Header设置

Header部分设置


此处注意将颜色设置为透明度255否则看不到边框!!!
此处注意将颜色设置为透明度255否则看不到边框!!!
此处注意将颜色设置为透明度255否则看不到边框!!!

Title部分设置


DeleteButton部分设置


效果展示:

这里我们展示标头的设置,以及我们的按钮设置那么我们进入我们的第二部分内容:照片,姓名,ID的展示,但是我们现在可以往下拉,找不到照片和数字输入字母输入的内容,那么照片我们时可以使用VisualElement的背景图片来实现的但是我们怎么实现整形,字符串的输入呢,OK我们可以添加在左下角有一个省略号我们点击并选择Editor Extension Authoring

会出现上述界面不用担心,就是会出现这种情况的不同担心,那么我们往下拉Library就会发现多了许多组件我们,那么我们正式开始
这个呢是我们将需要的组件托上去之后的效果没有做任何更改,那么我们需要输入ID,姓名,图片Icon,世界图片四个内容,就如下面所示

Icon部分设置


这里我的背景图片使用的是我自己的Icon大家可以自定义自己的默认Icon,接着我们再调整一下我们的父物体使其能够中间对齐

OK了搞定了这个之后我们再来解决我们那些输入的问题我们一个个来
首先先命名

ID

名字

Icon

世界图标


效果展示

那么现在我们的上班部分我们就完成了然后这个时候我们的Object Type还没确定,我们再ItemBase中使用的是Sprite那么这里我们也是用Sprite那么实现起来就简单的许多我演示一下另一个也是相同的操作

这样就OK了另外一个World Sprite也是相同的,这里我就不演示了。

那么我们进行最后一部分:底部部分的编辑。
底部编辑

此处我们可以看到我在内容管理里面只设置一个ItemType的类型为什么,因为我在ItemBase中我只定义了有关的Content内容那么大家伙只需要根据自己的需求定义即可,比如有些还有攻击力等属性我们都放在这个下面调整就Ok了
首当其冲当然是我们的Header

1.Title

BackGroundColor

ItemType



效果展示

完成!!!

好了到这我们的第一部分就完成了,剩下的我们下篇在讲,我先说一下,我们现在创建的这个ItemEditor的界面只是一个界面而已大家要认识到,但是我们需要根据自己的情况来解决这个问题那,我们的下篇文章将会实现他和我们代码的连接问题我们可以挨个实现这个内容,这个时候我们就可以保存以下打开Unity的编辑器中看一下怎么个事情了

结语

今天真是肝死我了,我这篇从早上八点起来写代码截图,到晚上八点钟才搞定,哎呀累死俺了,过几天就要考科二了,大家伙快快安慰一下马上就要考科二的主包吧!主包不想考科二啊啊啊啊!!!,我干了兄弟们,下篇我打算先让我缓个两天再说大家这两天赶紧先把自己额界面美化一下不要像主包这个这么丑,结语就是用来和大伙唠嗑的,暑假也没几天了,我打算就把背包系统的写完就不写了,接下来全心全意的做我的新项目去了,那么大家拜拜!!!

相关推荐
澡点睡觉28 分钟前
golang的包和闭包
开发语言·后端·golang
Dxy12393102161 小时前
python创建一个excel文件
开发语言·python·excel
朝朝又沐沐1 小时前
算法竞赛阶段二-数据结构(40)数据结构栈的STL
开发语言·数据结构·c++·算法
比特森林探险记2 小时前
Go语言常用的设计模式
开发语言·设计模式·golang
三千道应用题2 小时前
C#模式匹配用法与总结
c#
伽蓝_游戏2 小时前
Unity UI的未来之路:从UGUI到UI Toolkit的架构演进与特性剖析(6)
游戏·ui·unity·架构·c#·游戏引擎·.net
德育处主任Pro3 小时前
p5.js 用 beginGeometry () 和 endGeometry () 打造自定义 3D 模型
开发语言·javascript·3d
kyranhan3 小时前
C#程序本地运行正常,通过网络下载报错:FileLoadException:“未能加载文件或程序集“xxx.dll”或它的某一个依赖项。
开发语言·c#·wpf