关于1.21.2中物品的注册 1.21.2 Fabric
本篇教程的视频
(待发布)
本篇教程的源代码
(待发布)
本篇教程目标
- 理解原版物品注册(1.21.2)
- 学会物品注册(1.21.2)
注意
本篇教程为1.21 第一个物品
和1.21 第一个方块
的附属教程,
所以本篇教程只专注于讲解1.21.2
与1.21
之间的不同之处,后续的附属教程同理
1.21.2
和1.21
在物品/方块注册
上有些许不同,而像它们的模型
、方块状态文件
等并没有改变
所以我们这篇教程的主要任务在于搞清楚1.21.2
的物品/方块注册方法
推荐的学习路线是,先学习1.21
的教程,再来学习本教程
关于Blog提示
那么,如果说你用1.21
教程中的方法,到1.21.2
中注册物品,那么在启动游戏时,
游戏就崩溃
了,并抛出类似NullPointerException: Item id not set
异常
这个Item id
是个什么玩意?我们来看看Fabric Blog
上的介绍
1 | Minecraft 1.21.2 uses registry keys to pre-compute certain block or item settings. |
简单来说,Minecraft 1.21.2
中使用registry keys
(注册键)来预处理物品和方块的一些设置
现在物品和方块都有了一个与他们注册键相关联的组件
,其实就是他们的名字
,
这个名字呢,在语言文件缺失时,就会以item.命名空间.物品注册名
的形式显示
之前的版本中,有些地方要用到这个组件(比如显示名字),如果这个组件
缺失,
就会调用getName
方法来生成一个默认的名字
但是现在,所有物品和方块都包含这个组件了,如果你不给物品和方块设置注册键
,游戏就直接崩溃了
查看源代码
我们再结合源代码来看看这个注册键是怎么注册的
这里我们直接来看它的注册方法
1 | private static RegistryKey<Item> keyOf(String id) { |
可以看到,注册键是通过keyOf
方法生成的,而keyOf
方法又调用了Identifier.ofVanilla
方法
这个Identifier
在前面的教程中讲过了,ofVanilla
方法是以minecraft
为默认命名空间的,、
所以我们写的时候呢,得加上我们自己的命名空间
后面的注册方法与之前的版本有点区别,但不是很大,最后一个Registry.register(Registries.ITEM, key, item);
还是很熟悉吧
对于最后一个方法,在之前的版本中,第二个参数是Item item
,
现在变成了Function<Item.Settings, Item> factory
和Item.Settings settings
这两个参数呢,第一个是物品
的构造方法
,第二个是物品
的设置
Function
是Java
中的函数式接口,其泛型的第一个参数是函数输入的类型,第二个是函数结果的类型
那么放到这里来呢,根据传入的Item.Settings
创建并返回一个新的Item
实例
在方法内部呢,通过apply方法,再在已配置的Item.Settings
基础上再加上一个registryKey
方法,
这个方法就是用来给物品配置注册键的
1 | Item item = (Item)factory.apply(settings.registryKey(key)); |
这一串代码呢,你要简单理解,其实就是实例化一个物品
,类似于直接new Item
但对于实际开发而言,这就太局限了,因为像一些武器
、工具
,比如剑
、斧头
、镐子
等,
它们都有自己的物品类,这些类虽然是Item
的子类,但要实现它们特有的逻辑,
并不能直接new Item
,所以这里就用了Function
来实现更加灵活的注册
注册物品
那么这里我们就来注册自己的物品
注册方法
我们还是来先写注册方法,按照我的习惯还是将原版的那些方法进行整合,
如果你实在不会整合,就直接复制原版的那些方法好了,但记得改命名空间
1 | public static Item registerItems(String name, Function<Item.Settings, Item> factory, Item.Settings settings) { |
这里我们直接将keyOf
方法整合进来了,这样一个方法就能解决了
注册物品
再来注册物品
1 | public static final Item ICE_ETHER = registerItems("ice_ether", Item::new, new Item.Settings()); |
我们也可以拿以前版本的进行对比
1 | public static final Item ICE_ETHER = registerItems("ice_ether", new Item(new Item.Settings())); |
区别是显然易见的吧
后面的语言文件
、模型文件
和1.21
的是一样的,这里就不再赘述
参见:#2 第一个物品