Non résolu Faire des mouvement pour un véhicule en 1.20.1
-
Bonjour, j’ai fait un addons MCreator et suite à son petit succès sur Cursforge, je me suis déterminé à toucher réellement au code du mod pour corriger pas mal du bug relatif à MCreator et changer les déplacements de mon kart
Avant, il se dirigeait uniquement avec la vue du joueur et la touche pour avancer
mais j’aurais aimé faire un déplacement similaire au bateau, mais de façon terrestre
Après avoir cherché plein de tutos pour plein de trucs, je bloque sur les fameux mouvements…vu que mon but était de faire les mêmes mouvements qu’un bateau, j’ai naïvement cru que reprendre son code pour l’adapter serait une bonne solution
Mais… je n’arrive vraiment pas à faire fonctionner les inputs qui servaient au bateau…
Ça fait 1 semaine et je ne sais plus quoi tester…(attention, je suis nouveau en dev Java et Minecraft, ce code risque de brûler des rétines ^^ )
PS : j’utilise Geckolib pour le rendu du kart et les animations de l’entité__
KartEntity.java -> il y a en commentaire un marqueur pour mes modif “//mes modification à partir de ICI”package net.stalosir.createkart.entity; import net.minecraft.util.Mth; import net.minecraft.world.entity.*; import software.bernie.geckolib.util.GeckoLibUtil; import software.bernie.geckolib.core.object.PlayState; import software.bernie.geckolib.core.animation.RawAnimation; import software.bernie.geckolib.core.animation.AnimationState; import software.bernie.geckolib.core.animation.AnimationController; import software.bernie.geckolib.core.animation.AnimatableManager; import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache; import software.bernie.geckolib.animatable.GeoEntity; import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.network.PlayMessages; import net.minecraftforge.network.NetworkHooks; import net.minecraft.world.phys.Vec3; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.Level; import net.minecraft.world.item.ItemStack; import net.minecraft.world.entity.projectile.ThrownPotion; import net.minecraft.world.entity.projectile.AbstractArrow; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.damagesource.DamageTypes; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionHand; import net.minecraft.resources.ResourceLocation; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.network.protocol.Packet; import net.minecraft.nbt.CompoundTag; import net.minecraft.core.BlockPos; import net.stalosir.createkart.init.CreateKartModItems; import net.stalosir.createkart.init.CreateKartModEntities; import java.util.Objects; public class KartEntity extends PathfinderMob implements GeoEntity { public static final EntityDataAccessor<Boolean> SHOOT = SynchedEntityData.defineId(KartEntity.class, EntityDataSerializers.BOOLEAN); public static final EntityDataAccessor<String> ANIMATION = SynchedEntityData.defineId(KartEntity.class, EntityDataSerializers.STRING); public static final EntityDataAccessor<String> TEXTURE = SynchedEntityData.defineId(KartEntity.class, EntityDataSerializers.STRING); private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); public String animationprocedure = "empty"; private boolean inputLeft; private boolean inputRight; private boolean inputUp; private boolean inputDown; private float deltaRotation = 0.0F; public KartEntity(PlayMessages.SpawnEntity packet, Level world) { this(CreateKartModEntities.KART.get(), world); } public KartEntity(EntityType<KartEntity> type, Level world) { super(type, world); xpReward = 0; setNoAi(false); setMaxUpStep(1f); } @Override protected void defineSynchedData() { super.defineSynchedData(); this.entityData.define(SHOOT, false); this.entityData.define(ANIMATION, "undefined"); this.entityData.define(TEXTURE, "kart_texture"); } public void setTexture(String texture) { this.entityData.set(TEXTURE, texture); } public String getTexture() { return this.entityData.get(TEXTURE); } @Override public Packet<ClientGamePacketListener> getAddEntityPacket() { return NetworkHooks.getEntitySpawningPacket(this); } @Override protected void registerGoals() { super.registerGoals(); } @Override public MobType getMobType() { return MobType.UNDEFINED; } @Override public double getPassengersRidingOffset() { return super.getPassengersRidingOffset() + -0.9; } protected void dropCustomDeathLoot(DamageSource source, int looting, boolean recentlyHitIn) { super.dropCustomDeathLoot(source, looting, recentlyHitIn); this.spawnAtLocation(new ItemStack(CreateKartModItems.KART_ITEM.get())); } @Override public void playStepSound(BlockPos pos, BlockState blockIn) { this.playSound(Objects.requireNonNull(ForgeRegistries.SOUND_EVENTS.getValue(new ResourceLocation("create_kart:kart_stay_2s"))), 0.15f, 1); } @Override public boolean hurt(DamageSource source, float amount) { if (source.is(DamageTypes.IN_FIRE)) return false; if (source.getDirectEntity() instanceof AbstractArrow) return false; if (source.getDirectEntity() instanceof ThrownPotion || source.getDirectEntity() instanceof AreaEffectCloud) return false; if (source.is(DamageTypes.FALL)) return false; if (source.is(DamageTypes.CACTUS)) return false; if (source.is(DamageTypes.DROWN)) return false; if (source.is(DamageTypes.DRAGON_BREATH)) return false; if (source.is(DamageTypes.WITHER)) return false; if (source.is(DamageTypes.WITHER_SKULL)) return false; return super.hurt(source, amount); } @Override public void addAdditionalSaveData(CompoundTag compound) { super.addAdditionalSaveData(compound); compound.putString("Texture", this.getTexture()); } @Override public void readAdditionalSaveData(CompoundTag compound) { super.readAdditionalSaveData(compound); if (compound.contains("Texture")) this.setTexture(compound.getString("Texture")); } @Override public InteractionResult mobInteract(Player sourceentity, InteractionHand hand) { ItemStack itemstack = sourceentity.getItemInHand(hand); InteractionResult retval = InteractionResult.sidedSuccess(this.level().isClientSide()); super.mobInteract(sourceentity, hand); sourceentity.startRiding(this); return retval; } @Override public void baseTick() { super.baseTick(); this.refreshDimensions(); } @Override public EntityDimensions getDimensions(Pose p_33597_) { return super.getDimensions(p_33597_).scale((float) 1); } //mes modification à partir de ICI /*quelques modifications viennent sûrement de GPT, comme ça fait longtemps je ne saurais plus dire lesquelles */ @Override public void tick() { super.tick(); if (this.isControlledByLocalInstance()) { // Si le kart est contrôlé localement this.controlKart(); // Met à jour les entrées du joueur } } public void controlKart() { if (this.getControllingPassenger() instanceof Player player) { boolean left = player.zza < 0; // Reculer boolean right = player.xxa > 0; // Tourner à droite boolean forward = player.zza > 0; // Avancer boolean backward = player.xxa < 0; // Tourner à gauche this.setInput(left, right, forward, backward); } } @Override public void travel(Vec3 dir) { if (this.isVehicle()) { float speedFactor = 0.0F; // Facteur de vitesse float rotationSpeed = 3.0F; // Sensibilité de la rotation float forwardSpeed = 0.04F; // Vitesse de déplacement vers l'avant float backwardSpeed = -0.02F; // Vitesse de déplacement vers l'arrière // Gestion des touches (rotation gauche/droite) if (this.inputLeft) { this.deltaRotation -= rotationSpeed; } if (this.inputRight) { this.deltaRotation += rotationSpeed; } // Ajuste la rotation du kart this.setYRot(this.getYRot() + this.deltaRotation); this.setRot(this.getYRot(), this.getXRot()); // Met à jour l'orientation // Déplacement en avant/arrière if (this.inputUp) { speedFactor += forwardSpeed; } if (this.inputDown) { speedFactor += backwardSpeed; } // Calcul du mouvement en fonction de l'orientation double motionX = -Mth.sin(this.getYRot() * ((float) Math.PI / 180F)) * speedFactor; double motionZ = Mth.cos(this.getYRot() * ((float) Math.PI / 180F)) * speedFactor; this.setDeltaMovement(this.getDeltaMovement().add(motionX, 0.0D, motionZ)); } else { super.travel(dir); // Si personne ne conduit le kart, comportement par défaut } } //copier chez le bateau pour tester VVV public void setInput(boolean p_38343_, boolean p_38344_, boolean p_38345_, boolean p_38346_) { System.out.println("INPUT MODIFIER");//je ne le vois jamais lors des teste this.inputLeft = p_38343_; this.inputRight = p_38344_; this.inputUp = p_38345_; this.inputDown = p_38346_; } //fin de mes modification ICI @Override public boolean isControlledByLocalInstance() { return this.getControllingPassenger() instanceof Player; } @Override public void aiStep() { super.aiStep(); this.updateSwingTime(); } public static void init() { } public static AttributeSupplier.Builder createAttributes() { AttributeSupplier.Builder builder = Mob.createMobAttributes(); builder = builder.add(Attributes.MOVEMENT_SPEED, 0.20); builder = builder.add(Attributes.MAX_HEALTH, 2); builder = builder.add(Attributes.ARMOR, 0); builder = builder.add(Attributes.ATTACK_DAMAGE, 0); builder = builder.add(Attributes.FOLLOW_RANGE, 0); builder = builder.add(Attributes.KNOCKBACK_RESISTANCE, 1000); return builder; } private PlayState movementPredicate(AnimationState event) { if (this.animationprocedure.equals("empty")) { if ((event.isMoving() || !(event.getLimbSwingAmount() > -0.15F && event.getLimbSwingAmount() < 0.15F)) ) { return event.setAndContinue(RawAnimation.begin().thenLoop("animation.model.forward")); } return event.setAndContinue(RawAnimation.begin().thenLoop("animation.model.stay")); } return PlayState.STOP; } String prevAnim = "empty"; private PlayState procedurePredicate(AnimationState event) { if (!animationprocedure.equals("empty") && event.getController().getAnimationState() == AnimationController.State.STOPPED || (!this.animationprocedure.equals(prevAnim) && !this.animationprocedure.equals("empty"))) { if (!this.animationprocedure.equals(prevAnim)) event.getController().forceAnimationReset(); event.getController().setAnimation(RawAnimation.begin().thenPlay(this.animationprocedure)); if (event.getController().getAnimationState() == AnimationController.State.STOPPED) { this.animationprocedure = "empty"; event.getController().forceAnimationReset(); } } else if (animationprocedure.equals("empty")) { prevAnim = "empty"; return PlayState.STOP; } prevAnim = this.animationprocedure; return PlayState.CONTINUE; } @Override protected void tickDeath() { ++this.deathTime; if (this.deathTime == 20) { this.remove(KartEntity.RemovalReason.KILLED); this.dropExperience(); } } public String getSyncedAnimation() { return this.entityData.get(ANIMATION); } public void setAnimation(String animation) { this.entityData.set(ANIMATION, animation); } @Override public void registerControllers(AnimatableManager.ControllerRegistrar data) { data.add(new AnimationController<>(this, "movement", 4, this::movementPredicate)); data.add(new AnimationController<>(this, "procedure", 4, this::procedurePredicate)); } @Override public AnimatableInstanceCache getAnimatableInstanceCache() { return this.cache; } }