Flandre923
549 words
3 minutes
22 更改玩家的渲染的模型

22 更改玩家的渲染的模型#

我们使用上一次说的访问WalkAnimationState​的speedOld​,speed,position


@Mixin(WalkAnimationState.class)
public  interface LimbAnimatorAccessor {


    @Accessor("speedOld")
    float getSpeedOld();

    @Accessor("speedOld")
    void setSpeedOld(float speedOld);

    @Accessor
    float getSpeed();

    @Accessor
    void setSpeed(float speed);

    @Accessor
    float getPosition();

    @Accessor
    void setPosition(float pos);


}

如果是其他的实体,则在对应的位置生成一个羊,然后移除当初的实体


@Mixin(LivingEntity.class)
public abstract class LivingEntityMixin extends Entity implements Attackable {
    @Shadow public abstract boolean hasEffect(Holder<MobEffect> effect);

    public LivingEntityMixin(EntityType<?> entityType, Level level) {
        super(entityType, level);
    }


    @Inject(at = @At("HEAD"), method = "tick")
    private void init(CallbackInfo info) {
        if(!this.level().isClientSide) {
            if (this.hasEffect(ModEffects.SHEEP_EFFECT)) {//变羊药水
                if (!this.isAlwaysTicking()) {//如果不是玩家的话
                    Vec3 pos = this.position();
                        EntityType.SHEEP.spawn(((ServerLevel) this.level()), BlockPos.containing(pos), MobSpawnType.TRIGGERED);
                    this.remove(RemovalReason.KILLED);
                }
            }
        }
    }

}

如果是玩家的话,那么我们要调整 渲染将玩家渲染为羊,这个思路和之前的物品的渲染类似.

// 指定这是一个混入类,将功能添加到 PlayerRenderer 类。
// 这允许我们修改 PlayerRenderer 的渲染行为,而无需直接修改 PlayerRenderer 的源代码。
@Mixin(PlayerRenderer.class)
public abstract class PlayerEntityRendererMixin extends LivingEntityRenderer<AbstractClientPlayer, PlayerModel<AbstractClientPlayer>> {

    // 构造函数,用于初始化 PlayerEntityRendererMixin 类。
    // 调用父类 LivingEntityRenderer 的构造函数。
    public PlayerEntityRendererMixin(EntityRendererProvider.Context context, PlayerModel<AbstractClientPlayer> model, float shadowRadius) {
        super(context, model, shadowRadius);
    }

    // 使用 @Redirect 注解重定向 PlayerRenderer 的 render 方法。
    // 这意味着我们将拦截对 PlayerRenderer.render 方法的调用,并用自定义的逻辑替代它。
    @Redirect(
            method = "render*", // 拦截所有以 render* 开头的方法
            at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/entity/player/PlayerRenderer;render(Lnet/minecraft/client/player/AbstractClientPlayer;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V"))
    private void redirectRender(PlayerRenderer renderer, AbstractClientPlayer entity, float entityYaw, float partialTicks, PoseStack poseStack, MultiBufferSource buffer, int packedLight) {

        // 创建一个新的羊实体,使用当前游戏世界的实例。
        LivingEntity sheep = new Sheep(EntityType.SHEEP, Minecraft.getInstance().level);

        // 如果玩家有变羊效果
        if (entity.hasEffect(ModEffects.SHEEP_EFFECT)) {
            // 获取羊的渲染器
            EntityRenderer sheepRenderer = Minecraft.getInstance().getEntityRenderDispatcher().getRenderer(sheep);

            // 将玩家的动画属性复制到羊身上
            LimbAnimatorAccessor target = (LimbAnimatorAccessor) sheep.walkAnimation;
            LimbAnimatorAccessor source = (LimbAnimatorAccessor) entity.walkAnimation;
            target.setSpeedOld(source.getSpeedOld());
            target.setSpeed(source.getSpeed());
            target.setPosition(source.getPosition());
            // 同步其他动画参数
            sheep.swinging = entity.swinging;
            sheep.swingTime = entity.swingTime;
            sheep.oAttackAnim = entity.oAttackAnim;
            sheep.attackAnim = entity.attackAnim;
            sheep.yBodyRot = entity.yBodyRot;
            sheep.yBodyRotO = entity.yBodyRotO;
            sheep.yHeadRot = entity.yHeadRot;
            sheep.yHeadRotO = entity.yHeadRotO;
            sheep.tickCount = entity.tickCount;
            sheep.swingingArm = entity.swingingArm;
            sheep.setOnGround(entity.onGround());
            sheep.setDeltaMovement(entity.getDeltaMovement());

            // 同步姿态和角度
            sheep.setPose(entity.getPose());
            sheep.setXRot(entity.getXRot());
            sheep.xRotO = entity.xRotO;

            // 使用羊的渲染器渲染羊实体
            sheepRenderer.render(sheep, entityYaw, partialTicks, poseStack, buffer, packedLight);
        } else {
            // 如果玩家没有变羊效果,则调用父类的渲染方法来渲染玩家
            super.render((AbstractClientPlayer) entity, entityYaw, partialTicks, poseStack, buffer, packedLight);
        }
    }
}

22 更改玩家的渲染的模型
https://fuwari.vercel.app/posts/minecraft1_21_0/22_更改玩家的渲染的模型/
Author
Flandre923
Published at
2024-08-24