快轉到主要內容

Fabric + Geckolib模組新增生物實體教學

分類   遊戲攻略 Minecraft
標籤   Fabric Mod BlockBench
🗓️ 民國110年 辛丑年
✍ 切換正體/簡體字
目錄

實體的模型要如何一個格式多平台通用?透過Geckolib這個模組可以有效舒緩這個問題。

簡單來說,只要是用Blockbench製作的模型,透過Geckolib就可以同時用在Java版模組和基岩版的Add-On,還能夠製作實體動畫。

(左為Java版畫面,右邊為基岩版畫面)

這篇文章以Fabric為基礎,教學如何在Minecraft Java版1.17.1加入實體,並用Geckolib來套用模型。

1. 注意事項
#

開發模組使用Geckolib的話,別人玩你的模組前就必須安裝 Geckolib這個前置模組。

Geckolib有分forge版跟fabric版,下載時請抓有寫"fabric"的版本。

2. 準備模型檔案
#

要製作跨平台模型,應以基岩版格式為基礎,因為能無痛轉換成Geckolib格式。

  1. 首先轉換現有的模型。Blockbench安裝"Geckolib Animation Utils"插件。

  2. 按Files -> Convert Project,選擇"Geckolib Animated Model"

  1. 按Files -> Export  -> Export Geckolib Model

會得到一個json檔案,裡面只有記載模型資訊。材質的png檔案要另外匯出。

如果有動畫檔案,在Animation面板按下 Animation -> Export Animations,同樣會得到一個json檔案。

  1. fabric模組的材質大部分都在src/main/resources/assests/模組ID/

在這個例子中,我將模型檔案放在geo資料夾裡,叫做shimakaze.json

材質放在/entity/kanmusu/,叫做shimakaze.png

動畫放在/animations,叫做shimakaze.animation.json

3. 在fabric專案加入Geckolib依賴項目
#

  1. 開啟專案的build.gradle,加入Geckolib:
repositories {
	 maven { url 'https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/' }
}

dependencies {
	modImplementation 'software.bernie.geckolib:geckolib-fabric-1.17:3.0.13:dev'
}
  1. 開啟fabric.mod.json,註明要使用Geckolib。(fabric.mod.json也可以不聲明依賴Geckolib,但若出錯遊戲就會直接崩潰,而不是由Fabric提示玩家缺少Geckolib模組。)
  "depends": {
    "fabricloader": ">=0.11.6",
    "fabric": "*",
    "minecraft": "1.17.x",
    "java": ">=16",
    "geckolib3": "*"
  }

4. fabric實體的主程式寫法
#

fabric中建立實體需要以下檔案:

  • 註冊實體的class
  • 註冊渲染器的class (需在fabric.mod.json註明client entry)
  • 渲染器的class
  • 模型的lass

我的目錄結構長這樣:

模組會從Main.java開始,接著會呼叫ModEntities的registerEntities()方法,用這個class來註冊實體(->ShimakazeEntity.java)。

同時,EntityClinet.java會在初始化時註冊渲染器(->ShimakazeRenderer.java)。

ShimakazeEntity.java包含註冊實體的方法,以及定義實體的行為程式,但這裡僅加入一個靜止實體。

ShimakazeModel.java為最關鍵的一步,使用Geckolib來創造模型、材質、動畫。

ModEntities.java程式碼:

package net.mcbedev.kancolle.client;

import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry;
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder;
import net.mcbedev.kancolle.Main;
import net.mcbedev.kancolle.client.entity.ShimakazeEntity;
import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnGroup;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;

public class ModEntities {

  // 註冊實體
  public static final EntityType<ShimakazeEntity> SHIMAKAZE = Registry.register(Registry.ENTITY_TYPE,
      new Identifier(Main.MOD_ID, "shimakaze"), FabricEntityTypeBuilder
          .create(SpawnGroup.CREATURE, ShimakazeEntity::new).dimensions(EntityDimensions.fixed(0.5f, 2f)).build());

  public static void registerEntities() {
    // 註冊實體屬性
    FabricDefaultAttributeRegistry.register(SHIMAKAZE, ShimakazeEntity.createMobAttributes());
    System.out.println("Registering mod mobs for" + Main.MOD_ID);
  }

}

EntityClient.java程式碼:

package net.mcbedev.kancolle.client;

import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.impl.client.rendering.EntityRendererRegistryImpl;
import net.mcbedev.kancolle.client.renderer.ShimakazeRenderer;

@Environment(EnvType.CLIENT)
public class EntityClient implements ClientModInitializer {

    @Override
    public void onInitializeClient() {
        //註冊渲染器
        EntityRendererRegistryImpl.register(ModEntities.SHIMAKAZE, ShimakazeRenderer::new);

    }
}

ShimakazeEntity.java程式碼:

package net.mcbedev.kancolle.client.entity;

import net.minecraft.entity.EntityType;
import net.minecraft.entity.mob.PathAwareEntity;
import net.minecraft.world.World;
import software.bernie.geckolib3.core.IAnimatable;
import software.bernie.geckolib3.core.manager.AnimationData;
import software.bernie.geckolib3.core.manager.AnimationFactory;

public class ShimakazeEntity extends PathAwareEntity implements IAnimatable {
    private AnimationFactory factory = new AnimationFactory(this);

    public ShimakazeEntity(EntityType<? extends PathAwareEntity> type, World worldIn) {
        super(type, worldIn);
        this.ignoreCameraFrustum = true;
    }

    @Override
    public AnimationFactory getFactory() {
        return this.factory;
    }

    @Override
    public void registerControllers(AnimationData arg0) {

    }
}

ShimakazeRenderer.java程式碼:

package net.mcbedev.kancolle.client.renderer;

import net.mcbedev.kancolle.client.entity.ShimakazeEntity;
import net.mcbedev.kancolle.client.model.ShimakazeEntityModel;
import net.minecraft.client.render.entity.EntityRendererFactory;
import software.bernie.geckolib3.renderers.geo.GeoEntityRenderer;

public class ShimakazeRenderer extends GeoEntityRenderer<ShimakazeEntity> {
    public ShimakazeRenderer(EntityRendererFactory.Context renderManager) {
        super(renderManager, new ShimakazeEntityModel());
    }
}

ShimakazeModel.java程式碼,跟第一步驟準備的路徑要一致。

package net.mcbedev.kancolle.client.model;

import net.mcbedev.kancolle.client.entity.ShimakazeEntity;
import net.minecraft.util.Identifier;
import software.bernie.geckolib3.model.AnimatedGeoModel;

public class ShimakazeEntityModel extends AnimatedGeoModel<ShimakazeEntity> {

    @Override
    public Identifier getModelLocation(ShimakazeEntity object) {
        return new Identifier("kancollemod", "geo/shimakaze.json");
    }

    @Override
    public Identifier getTextureLocation(ShimakazeEntity object) {
        return new Identifier("kancollemod", "textures/entity/kanmusu/shimakaze.png");
    }

    @Override
    public Identifier getAnimationFileLocation(ShimakazeEntity animatable) {
        return new Identifier("kancollemod", "animations/shimakaze.animation.json");
    }
}

在處理完import的問題之後,實際在遊戲中測試,用指令/summon kancolle:shimakaze,會召喚靜止狀態的島風。

相關文章

Ivon的Minecraft 3D模型作品
分類   遊戲攻略 Minecraft
標籤   BlockBench
Blockbench技巧:Box UV vs Pre-face UV
分類   遊戲攻略 Minecraft
標籤   BlockBench Minecraft Add-On
Blockbench模型前後顛倒解決辦法
分類   遊戲攻略 Minecraft
標籤   BlockBench

留言板

此處提供二種留言板。點選按鈕,選擇您覺得方便的留言板。要討論程式碼請用Giscus,匿名討論請用Disqus。

這是Giscus留言板,需要Github帳號才能留言。支援markdown語法,若要上傳圖片請貼Imgur連結。您的留言會在Github Discussions向所有人公開。

這是Disqus留言板,您可能會看到Disqus強制投放的廣告。有時留言可能會被系統判定需審核,導致延遲顯示,請見諒。