本文最后更新于 780 天前。
适用版本 | 1.15.2± |
平台 | Forge |
Mappings | snapshot_20210309 |
Minecraft Forge Mod开发中,注册物品/方块等有多种方法,比较常用的是DeferredRegister
在创建实例的同时也完成了注册,不像监听RegistryEvent
需要把两者分开,但注册后返回的实例是RegistryObject<?>
,每次调用时都需要调用get()
方法,不但不方便,而且如果调用的时机不对,还会触发空指针。
我遇到过最典型的问题,便是在1.15.2中向生物群系添加生物生成。Biome
中提供了addSpawn()
方法,即向生物群系添加生物生成,里面要求传入一个Entity
。这个方法在注册生物群系时将被调用。但无论你怎么搞,只要传入的实体是用的get()
方法,都会引发空指针异常。因为Minecraft的注册是有顺序的,即实体在生物群系之后注册。在注册生物群系时就调用了addSpawn()
方法。但此时实体还没被注册,因此get()
方法获取到的是null
,引发了空指针。
我想了很久,后来参考了Minecraft原版的注册方法,思路大体是这样的:(以Item为例)
- 创建一个方法,要求传入Item及物品ID。
- 用DeferredRegister进行注册。
- 返回传入的Item。
所以,代码是这样的:
public static final DeferredRegister<Item> ITEMS = new DeferredRegister<>(ForgeRegistries.ITEMS, "yourmodid");
private static Item register(String name, Item item) {
ITEMS.register(name, () -> item);
return item;
}
所以以后就是这样注册的了:
public static final Item YOUR_ITEM = register("item_name", new Item(<...>));