好像已经有两个月没写博客了呢…… 最近正在进行ayame的开发,遇到了这个难题,不过好在解决了,所以就分享出来吧。
前言
GeckoLib
是一个很流行的Minecraft动画库,如题,这篇文章要讲的就是如何动态加载模型(例如从文件或远程URL获取模型并加载)
编写这篇文章使用的Minecraft
版本为1.21
,GeckoLib
版本为4.5.8
,映射表为官方映射表,其它版本可能不适用
创建缓存
第一步实现创建缓存,目的是为了方便后续的调用。假设你的Entity类是CMEntity
,只需要创建三个Map<CMEntity,ResourceLocation>
,像下面这样:
1 | public static Map<CMEntity,ResourceLocation> modelCache = new HashMap<>(); // 模型缓存 |
向GeckoLib缓存写入模型和动画
既然要动态加载,首先就要写入GeckoLib的缓存,也就是GeckoLibCache
这个类。它提供了两个静态的getter方法:getBakedAnimations()
和getBakedModels()
,通过它们可以获取到缓存的Map。因此,我们就可以向Map里面添加值。
添加模型
通过getBakedModels()
方法可以得到一个Map<ResourceLocation,BakedGeoModel>
,接下来我们就需要往里面添加我们的模型。
1 | ResourceLocation loc = ResourceLocation.fromNamespaceAndPath("mod_id","geo/entity/cmentity/model_0.json"); // 请换成你自己的模组ID,Path可以随意,只要保证是json就行 |
到这里,模型缓存写入完成。
添加动画
动画的操作和模型类似,只需要如下即可:
1 | ResourceLocation loc = ResourceLocation.fromNamespaceAndPath("mod_id","animations/entity/cmentity/animation_0.json"); // 请换成你自己的模组ID,Path可以随意,只要保证是json就行 |
到这里,模型和动画就算完成。
添加贴图
贴图不直接由GeckoLib管理,而是由Minecraft直接管理,所以它不在geckoLib缓存中。
添加贴图只需要在TextureManager中注册即可。代码如下:
1 | InputStream stream = ... // 从文件或url等获取到的输入流,也可以使用byte[]代替 |
到这里,贴图的添加也算完成了。
创建GeoModel
这一步大家应该都会,GeckoLib官方wiki上也是有的,就不多赘述了,这里我们主要讲如何从缓存获取。
我们直接看下面重写的这三个方法:
1 |
|
完成了这些,那么恭喜你,已经大功告成了,接下来只需要优化细节即可。
折腾过程
正文结束,接下来讲讲我是怎么折腾的以及为什么会去做这个。
最近在进行Ayame的开发,它是一个用于自定义玩家模型的模组,使用GeckoLib作为前置,正常情况下修改模型是通过资源包的方式实现,不过对于玩家而言,使用资源包太过麻烦了,因此,能直接从文件或者链接加载模型显然更为方便,不过这需要动态加载模型了。最开始我是尝试使用Minecraft的资源管理器来实现动态加载,但是折腾了一天无果,遂放弃,也想过其它办法,但是大多不太行,最后选择了修改GeckoLib的缓存来实现它,没想到它确实有效,不过它只能加载模型和动画文件,不支持贴图,在翻阅代码后发现贴图依然是由原版在处理。在翻阅大量代码后,最后找到了贴图管理器,于是尝试使用它,没想到它确实有效,至此,动态加载模型也算完成了,距离Ayame的又进一步