1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > Minecraft 1.19.2 Forge模组开发 03.动画生物实体

Minecraft 1.19.2 Forge模组开发 03.动画生物实体

时间:2020-10-31 07:26:35

相关推荐

Minecraft 1.19.2 Forge模组开发 03.动画生物实体

1.12.2动画生物实体教程

1.16.5动画生物实体教程

1.18.2动画生物实体教程

效 果 展 示 效果展示 效果展示

我们本次尝试在1.19.2中添加一个能够具有各种动画效果动作的生物实体。

1.首先,为了实现这些动画效果,我们需要首先使用到一个模组:geckolib(下载地址)

找到项目的build.gradle文件,在repositoriesdependencies中添加依赖。

repositories {//添加这个maven { url 'https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/' }}dependencies {minecraft 'net.minecraftforge:forge:1.19.2-43.1.1'//添加这个implementation fg.deobf('software.bernie.geckolib:geckolib-forge-1.19:3.1.36')}

之后点击Load Gradle按钮重新构建项目

构建好了项目后在项目的Main类中添加一句geckolib的初始化语句:

Main.java

public Main(){IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();// Register the commonSetup method for modloadingbus.addListener(this::commonSetup);bus.addListener(this::setup);ItemInit.ITEMS.register(bus);BlockInit.BLOCKS.register(bus);EntityInit.ENTITY_TYPES.register(bus);//添加这个GeckoLib.initialize();MinecraftForge.EVENT_BUS.register(this);}

2.之后,与之前的教程一样,我们需要在blockbench中制作一个模组中的生物实体:

进入软件后我们要找到一个插件按钮,然后再搜索栏中输入GeckoLib Animation Utils,并下载这个插件

将我们制作好的生物实体进行模型转换工作,找到Convert Project,之后选择Geckolib Animated Model

在这之后,你会发现你的生物实体栏多了一个Animate栏,点击进去:

具体动作制作的视频:Blockbench动画制作

在制作好所有的动画后我们导出模型和动画json文件。

3.模型制作完成,接下来需要制作生物实体类,因为我们的生物的动作有很多,所以要在生物的不同状态时做出对应的动作。

EntitySamca.java

package com.joy187.re8joymod.entity;import java.util.EnumSet;import net.minecraft.sounds.SoundEvents;import net.minecraft.world.entity.EntityType;import net.minecraft.world.entity.LivingEntity;import net.minecraft.world.entity.Mob;import net.minecraft.world.entity.ai.attributes.AttributeSupplier;import net.minecraft.world.entity.ai.attributes.Attributes;import net.minecraft.world.entity.ai.goal.FloatGoal;import net.minecraft.world.entity.ai.goal.Goal;import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal;import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal;import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal;import net.minecraft.world.entity.animal.IronGolem;import net.minecraft.world.entity.monster.Monster;import net.minecraft.world.entity.monster.Vex;import net.minecraft.world.entity.player.Player;import net.minecraft.world.entity.raid.Raider;import net.minecraft.world.level.Level;import net.minecraft.world.phys.Vec3;import software.bernie.geckolib3.core.IAnimatable;import software.bernie.geckolib3.core.PlayState;import software.bernie.geckolib3.core.builder.AnimationBuilder;import software.bernie.geckolib3.core.controller.AnimationController;import software.bernie.geckolib3.core.event.predicate.AnimationEvent;import software.bernie.geckolib3.core.manager.AnimationData;import software.bernie.geckolib3.core.manager.AnimationFactory;public class EntitySamca extends Vex implements IAnimatable{private AnimationFactory factory = new AnimationFactory(this);public EntitySamca(EntityType<? extends Vex> type, Level worldIn) {super(type, worldIn);this.xpReward = 20;}public static AttributeSupplier.Builder prepareAttributes() {return Monster.createMonsterAttributes().add(Attributes.MAX_HEALTH, 35.0D).add(Attributes.ATTACK_DAMAGE, 8.5D).add(Attributes.MOVEMENT_SPEED, 0.28D).add(Attributes.KNOCKBACK_RESISTANCE, 0.15D);}protected void registerGoals() {super.registerGoals();this.goalSelector.addGoal(0, new FloatGoal(this));this.goalSelector.addGoal(4, new ChargeAttackGoal());this.goalSelector.addGoal(9, new LookAtPlayerGoal(this, Player.class, 3.0F, 1.0F));this.goalSelector.addGoal(10, new LookAtPlayerGoal(this, Mob.class, 8.0F));this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, Raider.class)).setAlertOthers());this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, true));//this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, EntityEthan.class, true));this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, IronGolem.class, true));}//我们生物的AI,决定使用哪种攻击方式class ChargeAttackGoal extends Goal {public ChargeAttackGoal() {this.setFlags(EnumSet.of(Flag.MOVE));}public boolean canUse() {if (EntitySamca.this.getTarget() != null && !EntitySamca.this.getMoveControl().hasWanted() && EntitySamca.this.random.nextInt(7) == 0) {return EntitySamca.this.distanceToSqr(EntitySamca.this.getTarget()) > 4.0D;} else {return false;}}public boolean canContinueToUse() {return EntitySamca.this.getMoveControl().hasWanted() && EntitySamca.this.isCharging() && EntitySamca.this.getTarget() != null && EntitySamca.this.getTarget().isAlive();}public void start() {LivingEntity livingentity = EntitySamca.this.getTarget();Vec3 vector3d = livingentity.getEyePosition(1.0F);EntitySamca.this.moveControl.setWantedPosition(vector3d.x, vector3d.y, vector3d.z, 1.0D);EntitySamca.this.setIsCharging(true);EntitySamca.this.playSound(SoundEvents.VEX_CHARGE, 1.0F, 1.0F);}public void stop() {EntitySamca.this.setIsCharging(false);}public void tick() {LivingEntity livingentity = EntitySamca.this.getTarget();if (EntitySamca.this.getBoundingBox().intersects(livingentity.getBoundingBox())) {EntitySamca.this.doHurtTarget(livingentity);EntitySamca.this.setIsCharging(false);} else {double d0 = EntitySamca.this.distanceToSqr(livingentity);if (d0 < 9.0D) {Vec3 vector3d = livingentity.getEyePosition(1.0F);EntitySamca.this.moveControl.setWantedPosition(vector3d.x, vector3d.y, vector3d.z, 1.0D);}}}}//该状态播放器控制生物的各种动作private <E extends IAnimatable> PlayState predicate(AnimationEvent<E> event) {//找到了敌人,就播放攻击动画if (this.isCharging()) {event.getController().setAnimation(new AnimationBuilder().playOnce("animation.samca.attack"));this.attackAnim=1;return PlayState.CONTINUE;}//平时就是飞行动画event.getController().setAnimation(new AnimationBuilder().addAnimation("animation.samca.fly", true));return PlayState.CONTINUE;}//将我们之前的所有动画控制器进行注册@Overridepublic void registerControllers(AnimationData data) {data.addAnimationController(new AnimationController(this, "controller",0, this::predicate));}@Overridepublic AnimationFactory getFactory() {return this.factory;}}

4.新建生物实体模型文件ModelDund类

ModelSamca.java

package com.joy187.re8joymod.entity.model;import com.joy187.re8joymod.Main;import com.joy187.re8joymod.entity.EntitySamca;import net.minecraft.client.model.geom.ModelLayerLocation;import net.minecraft.resources.ResourceLocation;import software.bernie.geckolib3.model.AnimatedGeoModel;public class ModelSamca extends AnimatedGeoModel<EntitySamca>{public static final ModelLayerLocation LAYER_LOCATION = new ModelLayerLocation(new ResourceLocation(Main.MOD_ID, "samca"), "main");@Overridepublic ResourceLocation getModelResource(EntitySamca object) {return new ResourceLocation(Main.MOD_ID, "geo/samca.geo.json");}@Overridepublic ResourceLocation getTextureResource(EntitySamca object) {return new ResourceLocation(Main.MOD_ID, "textures/entity/dund2.png");}@Overridepublic ResourceLocation getAnimationResource(EntitySamca animatable) {return new ResourceLocation(Main.MOD_ID, "animations/samca.animation.json");}}

5.模型部分结束,开始着手渲染类的编写。新建RenderDund类。

RenderDund.java

package com.joy187.re8joymod.entity.render;import com.joy187.re8joymod.Main;import com.joy187.re8joymod.entity.EntitySamca;import com.joy187.re8joymod.entity.model.ModelSamca;import com.mojang.blaze3d.vertex.PoseStack;import com.mojang.blaze3d.vertex.VertexConsumer;import net.minecraft.client.renderer.MultiBufferSource;import net.minecraft.client.renderer.RenderType;import net.minecraft.client.renderer.entity.EntityRendererProvider;import net.minecraft.resources.ResourceLocation;import software.bernie.geckolib3.renderers.geo.GeoEntityRenderer;public class RenderSamca extends GeoEntityRenderer<EntitySamca>{public RenderSamca(EntityRendererProvider.Context renderManager) {super(renderManager, new ModelSamca());this.shadowRadius = 0.5f;}@Overridepublic ResourceLocation getTextureLocation(EntitySamca instance) {//return LOCATION_BY_VARIANT.get(instance.getVariant());return new ResourceLocation(Main.MOD_ID, "textures/entity/dund2.png");}@Overridepublic RenderType getRenderType(EntitySamca animatable, float partialTicks, PoseStack stack,MultiBufferSource renderTypeBuffer, VertexConsumer vertexBuilder, int packedLightIn,ResourceLocation textureLocation) {// if(animatable.isBaby()) {// stack.scale(0.4F, 0.4F, 0.4F);// } else {// stack.scale(0.8F, 0.8F, 0.8F);// }stack.scale(1F, 1F, 1F);return super.getRenderType(animatable, partialTicks, stack, renderTypeBuffer, vertexBuilder, packedLightIn, textureLocation);}}

6.在EntityInit.java中添加我们的生物信息:

package com.joy187.re8joymod.init;import com.joy187.re8joymod.Main;import com.joy187.re8joymod.entity.EntitySamca;import net.minecraft.resources.ResourceLocation;import net.minecraft.world.entity.EntityType;import net.minecraft.world.entity.MobCategory;import net.minecraftforge.registries.DeferredRegister;import net.minecraftforge.registries.ForgeRegistries;import net.minecraftforge.registries.RegistryObject;public class EntityInit {public static final DeferredRegister<EntityType<?>> ENTITY_TYPES = DeferredRegister.create(ForgeRegistries.ENTITY_TYPES,Main.MOD_ID);public static final RegistryObject<EntityType<EntitySamca>> SAMCA = ENTITY_TYPES.register("samca",() -> EntityType.Builder.of(EntitySamca::new, MobCategory.MONSTER).sized(1f,1.8f).setTrackingRange(20).build(new ResourceLocation(Main.MOD_ID, "samca").toString()));}

ClientModEventSubscriber.java中添加我们的模型渲染、属性注册语句:

@Mod.EventBusSubscriber(modid = Main.MOD_ID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD)public class ClientModEventSubscriber{@SubscribeEventpublic static void onRegisterRenderer(EntityRenderersEvent.RegisterRenderers event) {//添加渲染注册语句event.registerEntityRenderer(EntityInit.SAMCA.get(), RenderSamca::new);//event.registerEntityRenderer(EntityInit.DETONATOR_ENTITY.get(), RenderDetonatorEntity::new);}@SubscribeEventpublic static void onAttributeCreate(EntityAttributeCreationEvent event) {//添加属性注册语句event.put(EntityInit.SAMCA.get(), EntitySamca.prepareAttributes().build());}}

7.生物实体部分结束,接下来我们要给生物制作一个刷怪蛋:

在ItemInit类中添加我们的刷怪蛋物品:

public static final RegistryObject<Item> SAMCA_SPAWN_EGG = ITEMS.register("samca_spawn_egg",() -> new ForgeSpawnEggItem(EntityInit.SAMCA, 3093009, 4390912, new Item.Properties().tab(Main.TUTORIAL_TAB)));

8.代码部分结束,来到资源包制作环节

resources\assets\你的modid中的lang包中的en_us.json添加刷怪蛋和生物实体英文名称:

"item.re8joymod.samca_spawn_egg": "Mob Spawn Egg","entity.re8joymod.samca": "Mob",

models\item包中添加刷怪蛋模型文件:

samca_spawn_egg.json

{"parent": "item/template_spawn_egg"}

textures\entity中添加生物实体的皮肤贴图

新建一个geo包和animation包,把第二步中的模型和动画文件分别放进去

9.最后我们还要给这个生物设定其掉落物

resources\data\你的modid中新建loot_tables包->loot_tables包中新建entities包 ->entities包中新建我们的战利品文件samaca.json

战利品文件中参数含义

name为物品名称,weight为掉落权重,越大掉这个物品的概率越高,count为掉落个数,min为最小掉几个,max为最大掉几个。

samaca.json

{"pools": [{"rolls": 1.0,"bonus_rolls": 0.0,"entries": [{"type": "item","name": "re8joymod:lei","weight": 5,"functions": [{"function": "set_count","count": {"min": 1,"max": 3}},{"function": "looting_enchant","count": {"min": 0,"max": 1}}]},{"type": "item","weight": 10,"name": "minecraft:iron_nugget","functions": [{"function": "set_count","count": {"min": 2,"max": 3}}]},{"type": "item","weight": 10,"name": "minecraft:rotten_flesh","functions": [{"function": "set_count","count": {"min": 0,"max": 2}}]},{"type": "item","weight": 5,"name": "re8joymod:blacksheephead","functions": [{"function": "set_count","count": {"min": 0,"max": 2}}]}]}]}

10.保存所有文件 -> 进行测试:

起飞!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。