[Mod编写经验] 注册的正确方式(防止空指针)
本文最后更新于 979 天前。
适用版本1.15.2±
平台Forge
Mappingssnapshot_20210309
版本不一定完全对应

Minecraft Forge Mod开发中,注册物品/方块等有多种方法,比较常用的是DeferredRegister在创建实例的同时也完成了注册,不像监听RegistryEvent需要把两者分开,但注册后返回的实例是RegistryObject<?>,每次调用时都需要调用get()方法,不但不方便,而且如果调用的时机不对,还会触发空指针。

我遇到过最典型的问题,便是在1.15.2中向生物群系添加生物生成。Biome中提供了addSpawn()方法,即向生物群系添加生物生成,里面要求传入一个Entity。这个方法在注册生物群系时将被调用。但无论你怎么搞,只要传入的实体是用的get()方法,都会引发空指针异常。因为Minecraft的注册是有顺序的,即实体在生物群系之后注册。在注册生物群系时就调用了addSpawn()方法。但此时实体还没被注册,因此get()方法获取到的是null,引发了空指针。

我想了很久,后来参考了Minecraft原版的注册方法,思路大体是这样的:(以Item为例)

  1. 创建一个方法,要求传入Item及物品ID。
  2. 用DeferredRegister进行注册。
  3. 返回传入的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(<...>));
上一篇
下一篇