详细情况如下
https://www.mcbbs.net/forum.php?mod=viewthread&tid=1484155&page=1#pid29400264
"implements GeoEntity"是动画实体的部分对实体本身没有影响
https://www.mcbbs.net/forum.php?mod=viewthread&tid=1484155&page=1#pid29400264
"implements GeoEntity"是动画实体的部分对实体本身没有影响
https://boson.v2mcdev.com/entity/scratchentity.html
https://boson.v2mcdev.com/entity/passiveentityandai.html你看的是哪个教程?
可以看到这里并没有非常艰深的内容。首先我们从一个非常值得注意的地方说起。
@Override
public IPacket<?> createSpawnPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
因为实体是在服务端创建以后再通知客户端创建,所以这里涉及到了发包操作,我们不能再这里复用Minecraft原版提供的方法,这里必须使用Forge提供的NetworkHooks.getEntitySpawningPacket(this);来在客户端创建实体。
https://boson.v2mcdev.com/entity/passiveentityandai.html
我们来看构造方法。
protected ObsidianAnimal(EntityType<? extends AnimalEntity> type, World worldIn) {
super(type, worldIn);
this.goalSelector.addGoal(0, new ObsidianGoal(this));
this.getAttributeManager().createInstanceIfAbsent(Attributes.MAX_HEALTH);
}
在这里我们调用 this.goalSelector.addGoal方法为我们的实体添加了一个AI或者说Goal(目的),而我们用this.getAttributeManager().createInstanceIfAbsent(Attributes.MAX_HEALTH);为我们的实体添加了一个属性,请注意Attributes.MAX_HEALTH这个属性是必须要添加的
接下来的我们来看看属性的注册。
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
public class AttributesSetEvent {
@SubscribeEvent
public static void setupAttributes(FMLCommonSetupEvent event) {
event.enqueueWork(() -> {
GlobalEntityTypeAttributes.put(EntityTypeRegistry.obsidianAnimal.get(), MobEntity.func_233666_p_().createMutableAttribute(Attributes.MAX_HEALTH, 10.0D).create());
});
}
}
可以看到,我们在FMLCommonSetupEvent这个事件中为我们的实体添加了属性,请注意这里的内容必须要放在event.enqueueWork中。
无敌三脚猫 发表于 2024-1-5 15:43
https://boson.v2mcdev.com/entity/scratchentity.html
https://boson.v2mcdev.com/entity/passiveentityan ...
抱歉哈,没看仔细。getAddEntityPacket是编译器直接生成的没注意。
GlobalEntityTypeAttributes.put方法已经被弃用,目前貌似就是event.put

this.getAttributeManager().createInstanceIfAbsent我没有找到应该是1.16.5改动了,我不太确定是那个是对应的方法目前找到这个 this.getAttributes().addTransientAttributeModifiers(Multimap<Attribute, AttributeModifier> p_233793_1_);但我不太清楚应该怎样填写这个
数据system 发表于 2024-1-5 16:23
抱歉哈,没看仔细。我直接照着mod里附带示例来写了。getAddEntityPacket是编译器直接生成的没注意。
Globa ...
这个教程用的是mcp反混淆表,比如他写的createSpawnPacket就相当于你写的getAddEntityPacket,当然还有一个共通的srg名func_213297_N
https://linkie.shedaniel.me/mappings可查
getAttributeManager().createInstanceIfAbsent应该对应getAttributes().getInstance
无敌三脚猫 发表于 2024-1-5 16:45
这个教程用的是mcp反混淆表,比如他写的createSpawnPacket就相当于你写的getAddEntityPacket,当然还有一 ...
还是一样报错,无论是用FMLCommonSetupEvent还是EntityAttributeCreationEvent

- package com.example.examplemod;
- import mod.azure.azurelib.animatable.GeoEntity;
- import mod.azure.azurelib.core.animatable.instance.AnimatableInstanceCache;
- import mod.azure.azurelib.core.animation.AnimatableManager;
- import mod.azure.azurelib.core.animation.AnimationController;
- import mod.azure.azurelib.core.animation.RawAnimation;
- import mod.azure.azurelib.util.AzureLibUtil;
- import net.minecraft.entity.*;
- import net.minecraft.entity.ai.attributes.AttributeModifierManager;
- import net.minecraft.entity.ai.attributes.Attributes;
- import net.minecraft.entity.ai.goal.LookAtGoal;
- import net.minecraft.entity.passive.AnimalEntity;
- import net.minecraft.entity.player.PlayerEntity;
- import net.minecraft.nbt.CompoundNBT;
- import net.minecraft.network.IPacket;
- import net.minecraft.network.datasync.DataParameter;
- import net.minecraft.network.datasync.DataSerializers;
- import net.minecraft.network.datasync.EntityDataManager;
- import net.minecraft.world.World;
- import net.minecraft.world.server.ServerWorld;
- import net.minecraftforge.fml.network.NetworkHooks;
- import javax.annotation.Nullable;
- public class TestEntity extends CreatureEntity implements GeoEntity {
- private final AnimatableInstanceCache cache = AzureLibUtil.createInstanceCache(this);
- public TestEntity(EntityType<? extends CreatureEntity> p_i48580_1_, World p_i48580_2_) {
- super(p_i48580_1_, p_i48580_2_);
- this.getAttributes().getInstance(Attributes.MAX_HEALTH);
- }
- @Override
- public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
- controllers.add(new AnimationController<>(this, "controllerName", 0, event ->
- {
- return event.setAndContinue(
- // If moving, play the walking animation
- event.isMoving() ? RawAnimation.begin().thenLoop("walking"):
- // If not moving, play the idle animation
- RawAnimation.begin().thenLoop("idle"));
- }));
- }
- @Override
- public AnimatableInstanceCache getAnimatableInstanceCache() {
- return cache;
- }
- @Override
- protected void defineSynchedData() {
- }
- @Override
- public void readAdditionalSaveData(CompoundNBT p_70037_1_) {
- }
- @Override
- public void addAdditionalSaveData(CompoundNBT p_213281_1_) {
- }
- @Override
- public IPacket<?> getAddEntityPacket() {
- return NetworkHooks.getEntitySpawningPacket(this);
- }
- }
属性添加错误,你可以换一种方法给生物添加属性
private static class EntityAttributesRegisterHandler {
@SubscribeEvent
public void onEntityAttributeCreation(EntityAttributeCreationEvent event) {
AttributeModifierMap.MutableAttribute ammma = MobEntity.func_233666_p_();
ammma = ammma.createMutableAttribute(Attributes.MOVEMENT_SPEED, 0);
ammma = ammma.createMutableAttribute(Attributes.MAX_HEALTH, 1024);
ammma = ammma.createMutableAttribute(Attributes.ARMOR, 0);
ammma = ammma.createMutableAttribute(Attributes.ATTACK_DAMAGE, 0);
ammma = ammma.createMutableAttribute(Attributes.FLYING_SPEED, 0);
event.put(entity, ammma.create());
}
}
注册
FMLJavaModLoadingContext.get().getModEventBus().register(new EntityAttributesRegisterHandler());
这是我的生物
public static class CustomEntity extends MonsterEntity {
public CustomEntity(FMLPlayMessages.SpawnEntity packet, World world) {
this(entity, world);
}
public CustomEntity(EntityType<CustomEntity> type, World world) {
super(type, world);
experienceValue = 0;
setNoAI(false);
enablePersistence();
setCustomNameVisible(true);
setInvisible(false);
}
@Override
public IPacket<?> createSpawnPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
@Override
protected void registerGoals() {
super.registerGoals();
this.goalSelector.addGoal(1, new MeleeAttackGoal(this, 1.2, false));
this.goalSelector.addGoal(2, new RandomWalkingGoal(this, 1));
this.targetSelector.addGoal(3, new HurtByTargetGoal(this));
this.goalSelector.addGoal(4, new LookRandomlyGoal(this));
this.goalSelector.addGoal(5, new SwimGoal(this));
}
@Override
public void baseTick() {
super.baseTick();
}
@Nullable
@Override
public ILivingEntityData onInitialSpawn(IServerWorld worldIn, DifficultyInstance difficultyIn, SpawnReason reason, @Nullable ILivingEntityData spawnDataIn, @Nullable CompoundNBT dataTag) {
return super.onInitialSpawn(worldIn, difficultyIn, reason, spawnDataIn, dataTag);
}
public void livingTick() {
super.livingTick();
}
}
private static class EntityAttributesRegisterHandler {
@SubscribeEvent
public void onEntityAttributeCreation(EntityAttributeCreationEvent event) {
AttributeModifierMap.MutableAttribute ammma = MobEntity.func_233666_p_();
ammma = ammma.createMutableAttribute(Attributes.MOVEMENT_SPEED, 0);
ammma = ammma.createMutableAttribute(Attributes.MAX_HEALTH, 1024);
ammma = ammma.createMutableAttribute(Attributes.ARMOR, 0);
ammma = ammma.createMutableAttribute(Attributes.ATTACK_DAMAGE, 0);
ammma = ammma.createMutableAttribute(Attributes.FLYING_SPEED, 0);
event.put(entity, ammma.create());
}
}
注册
FMLJavaModLoadingContext.get().getModEventBus().register(new EntityAttributesRegisterHandler());
这是我的生物
public static class CustomEntity extends MonsterEntity {
public CustomEntity(FMLPlayMessages.SpawnEntity packet, World world) {
this(entity, world);
}
public CustomEntity(EntityType<CustomEntity> type, World world) {
super(type, world);
experienceValue = 0;
setNoAI(false);
enablePersistence();
setCustomNameVisible(true);
setInvisible(false);
}
@Override
public IPacket<?> createSpawnPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
@Override
protected void registerGoals() {
super.registerGoals();
this.goalSelector.addGoal(1, new MeleeAttackGoal(this, 1.2, false));
this.goalSelector.addGoal(2, new RandomWalkingGoal(this, 1));
this.targetSelector.addGoal(3, new HurtByTargetGoal(this));
this.goalSelector.addGoal(4, new LookRandomlyGoal(this));
this.goalSelector.addGoal(5, new SwimGoal(this));
}
@Override
public void baseTick() {
super.baseTick();
}
@Nullable
@Override
public ILivingEntityData onInitialSpawn(IServerWorld worldIn, DifficultyInstance difficultyIn, SpawnReason reason, @Nullable ILivingEntityData spawnDataIn, @Nullable CompoundNBT dataTag) {
return super.onInitialSpawn(worldIn, difficultyIn, reason, spawnDataIn, dataTag);
}
public void livingTick() {
super.livingTick();
}
}
wozhizhan 发表于 2024-1-5 19:26
属性添加错误,你可以换一种方法给生物添加属性
private static class EntityAttributesRegisterHandler {
...
开始就是用EntityAttributeCreationEvent添加属性,但现在无论是EntityAttributeCreationEvent.put还是GlobalEntityTypeAttributes.put都一样