Topic category: User side tutorials
This tutorial is a way to enable two player riding on an entity.
The link below shows you what you're done with.
STEP1
- Create a custom entity.
- Check the ride function.
- Save.
STEP2
- Open the Code Editor.
- Add an import.
import java.util.ArrayList;
import java.util.List;
- Modify the code.
The original code 1
*Change the 'test' part of the code to the 'name of the Workspace AND Entity name.'
public class TestEntity extends Monster {
public TestEntity(PlayMessages.SpawnEntity packet, Level world) {
this(TestModEntities.TEST.get(), world);
}
Changed code 1
public class TestEntity extends Monster {
private List<Entity> customPassengers = new ArrayList<>(); // Add Code
public TestEntity(PlayMessages.SpawnEntity packet, Level world) {
this(TestModEntities.TEST.get(), world);
}
The original code 2
@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;
}
Changed code 2
@Override
public InteractionResult mobInteract(Player sourceentity, InteractionHand hand) {
ItemStack itemstack = sourceentity.getItemInHand(hand);
InteractionResult retval = super.mobInteract(sourceentity, hand);
if (!this.customPassengers.contains(sourceentity) && this.customPassengers.size() < 2) { // Add Riding 2 players.
sourceentity.startRiding(this, true); // Add Code
customPassengers.add(sourceentity); // Add Code
}
return retval;
}
The original code 3
@Override
public void travel(Vec3 dir) {
Entity entity = this.getPassengers().isEmpty() ? null : (Entity) this.getPassengers().get(0);
if (this.isVehicle()) {
this.setYRot(entity.getYRot());
this.yRotO = this.getYRot();
this.setXRot(entity.getXRot() * 0.5F);
this.setRot(this.getYRot(), this.getXRot());
this.yBodyRot = entity.getYRot();
this.yHeadRot = entity.getYRot();
if (entity instanceof LivingEntity passenger) {
this.setSpeed((float) this.getAttributeValue(Attributes.MOVEMENT_SPEED));
float forward = passenger.zza;
float strafe = passenger.xxa;
super.travel(new Vec3(strafe, 0, forward));
}
double d1 = this.getX() - this.xo;
double d0 = this.getZ() - this.zo;
float f1 = (float) Math.sqrt(d1 * d1 + d0 * d0) * 4;
if (f1 > 1.0F)
f1 = 1.0F;
this.walkAnimation.setSpeed(this.walkAnimation.speed() + (f1 - this.walkAnimation.speed()) * 0.4F);
this.walkAnimation.position(this.walkAnimation.position() + this.walkAnimation.speed());
this.calculateEntityAnimation(true);
return;
}
super.travel(dir);
}
Changed code 3
@Override
public void travel(Vec3 dir) {
if (this.isVehicle() && !this.customPassengers.isEmpty()) { // Add Code
Entity entity = this.customPassengers.get(0); // Add Code
this.setYRot(entity.getYRot());
this.yRotO = this.getYRot();
this.setXRot(entity.getXRot() * 0.5F);
this.setRot(this.getYRot(), this.getXRot());
this.yBodyRot = entity.getYRot();
this.yHeadRot = entity.getYRot();
if (entity instanceof LivingEntity passenger) {
this.setSpeed((float) this.getAttributeValue(Attributes.MOVEMENT_SPEED));
float forward = passenger.zza;
float strafe = passenger.xxa;
super.travel(new Vec3(strafe, 0, forward));
}
double d1 = this.getX() - this.xo;
double d0 = this.getZ() - this.zo;
float f1 = (float) Math.sqrt(d1 * d1 + d0 * d0) * 4;
if (f1 > 1.0F)
f1 = 1.0F;
this.walkAnimation.setSpeed(this.walkAnimation.speed() + (f1 - this.walkAnimation.speed()) * 0.4F);
this.walkAnimation.position(this.walkAnimation.position() + this.walkAnimation.speed());
this.calculateEntityAnimation(true);
this.setMaxUpStep(1.0f); // Makes you climb the hill when you have a rider in the entity.
return;
}
super.travel(dir);
}
Lastly, please add the code.
public static AttributeSupplier.Builder createAttributes() {
AttributeSupplier.Builder builder = Mob.createMobAttributes();
builder = builder.add(Attributes.MOVEMENT_SPEED, 0.3);
builder = builder.add(Attributes.MAX_HEALTH, 10);
builder = builder.add(Attributes.ARMOR, 0);
builder = builder.add(Attributes.ATTACK_DAMAGE, 3);
builder = builder.add(Attributes.FOLLOW_RANGE, 16);
return builder;
}
//Please add the following code below this code.
@Override
protected void positionRider(Entity passenger, MoveFunction moveFunction) {
if (this.hasPassenger(passenger)) {
int passengerIndex = this.getPassengers().indexOf(passenger);
double offsetX = this.getX();
double offsetY = this.getY() + 1.0D + passenger.getMyRidingOffset(); // Change ride Y height
double offsetZ = this.getZ();
if (passengerIndex == 0) {
// Location of the first passenger
offsetX = this.getX();
offsetZ = this.getZ();
} else if (passengerIndex == 1) {
// Second passenger's position
offsetX = this.getX() - Math.sin(Math.toRadians(this.getYRot())) * -1.0D;
offsetZ = this.getZ() + Math.cos(Math.toRadians(this.getYRot())) * -1.0D;
}
passenger.setPos(offsetX, offsetY, offsetZ);
}
}
}
Save and test the code.
It was completed by exchanging many questions and answers with Copilot(AI) to find this method.
----------------------------------------------------------------------------------
STEP3
Save and test.
-----------------------------------------------------------------------------------
The locations of the two players are affected by the server
This part has not been resolved.
I will write a new tutorial if I solve it.
Thank you.
The problem of Step3 written on August 4th has been solved, thank you.
https://imgur.com/k6r7v67
Image of the entire code editor applied to the MCreator.
Sorry... there was a mistake with some tutorial codes.
The incorrectly entered part of this code should be sorted out.
I can't edit it now, so I'll edit it later.
this.calculateEntityAnimation(true);this.setMaxUpStep(1.0f); // Ensure the entity can step up higher blocks while traveling
this.setMaxUpStep(1.0f); // Makes you climb the hill when you have a rider in the entity.
return;
}
super.travel(dir);
}
edit
this.calculateEntityAnimation(true);
this.setMaxUpStep(1.0f); // Makes you climb the hill when you have a rider in the entity.
return;
}
super.travel(dir);
}
Neat!
I have checked the screenshot you sent multiple times. To reduce errors, my mod and entity are also called "tests", just like your example. Then mcreator successfully compiled Java, but crashed when starting mc. The client appeared for about two seconds and then crashed.
Sorry, I just realized that it seems to be a client issue. Even after deleting the entity, it still cannot start. I need to check first
I have successfully created a two player ride entity by following your tutorial. Thank you! That's amazing and I want to learn more!
How can I change only the riding position without increasing the number of passengers?
How can I make more than two player ride an entity?
I'm not a native English speaker. I'm sorry if I didn't express myself clearly
if (!this.customPassengers.contains(sourceentity) && this.customPassengers.size() < 2) { // Add Riding 2 players.
You can adjust the number of passengers by changing the number of people in this part.
@Override
protected void positionRider(Entity passenger, MoveFunction moveFunction) {
if (this.hasPassenger(passenger)) {
int passengerIndex = this.getPassengers().indexOf(passenger);
double offsetX = this.getX();
double offsetY = this.getY() + 1.0D + passenger.getMyRidingOffset(); // Change ride Y height
double offsetZ = this.getZ();
if (passengerIndex == 0) {
// Location of the first passenger
offsetX = this.getX();
offsetZ = this.getZ();
} else if (passengerIndex == 1) {
// Second passenger's position
offsetX = this.getX() - Math.sin(Math.toRadians(this.getYRot())) * -1.0D;
offsetZ = this.getZ() + Math.cos(Math.toRadians(this.getYRot())) * -1.0D;
} else if (passengerIndex == 2) {
// Third passenger's position
offsetX = this.getX() + Math.sin(Math.toRadians(this.getYRot())) * 1.0D;
offsetZ = this.getZ() - Math.cos(Math.toRadians(this.getYRot())) * 1.0D;
}
passenger.setPos(offsetX, offsetY, offsetZ);
}
}
Just add the index number and adjust the position.
You can modify the part that says the position is 1.0D.
In the latest version (2024.3)
double offsetY = this.getY() + 1.0D + passenger.getMyRidingOffset();
You have to do this to make it work.
Double offsetY = this.getY() + 1.0D;
You are a hero! I have been looking for a feasible solution to this exact problem for 2 years now. It is really important to the core idea of my mod.
Will try after i backup my workspace
I followed your tutorial and managed to add a second passenger but now, once I interact (right click) with the mount entity, I can then no longer interact with it again. Even dismounting from the mount entity (sneaking) does not register anymore.
Thanks again for taking your time for the tutorial!
Any idea would still be appreciated, though.
In 2024.2 version, the code worked fine, but in the latest version, the passenger list doesn't seem to reset.
Try fixing that part like this.
@Override
public InteractionResult mobInteract(Player sourceentity, InteractionHand hand) {
ItemStack itemstack = sourceentity.getItemInHand(hand);
InteractionResult retval = super.mobInteract(sourceentity, hand);
if (this.customPassengers.size() < 2) { // Only up to 2 people allowed
if (!sourceentity.isPassenger()) { // If the player is not currently boarding somewhere else
sourceentity.startRiding(this, true);
if (!customPassengers.contains(sourceentity)) { // If it's not on the list, add it
customPassengers.add(sourceentity);
}
}
}
return retval;
}
This is the full code.