Ein Blockzustand entspricht ein wenig Daten, die einem einzelnen Block in der Minecraft-Welt zugeordnet sind und Informationen über den Block in Form von Eigenschaften enthält - einige Beispiele für Eigenschaften, die Vanilla in Blockzuständen speichert:
- Rotation: Hauptsächlich für Baumstämme und andere natürliche Blöcke verwendet.
- Activated: Wird häufig in Redstone-Geräten und Blöcken wie dem Ofen oder dem Räucherofen verwendet.
- Age: Wird in Samen, Pflanzen, Setzlingen, Seetang, etc. verwendet
Du kannst wahrscheinlich sehen, warum sie nützlich sind - sie vermeiden die Notwendigkeit, NBT-Daten in einer Blockentität zu speichern - was die Weltgröße reduziert und TPS-Probleme verhindert!
Blockzustand-Definitionen finden sich im Ordner assets/example-mod/blockstates.
Beispiel: Säulenblock
Minecraft verfügt bereits über einige benutzerdefinierte Klassen, mit denen man schnell bestimmte Arten von Blöcken erstellen kann - in diesem Beispiel wird die Erstellung eines Blocks mit der Eigenschaft axis durch die Erstellung eines „Condensed Oak Log“-Blocks erläutert.
Die Vanilla RotatedPillarBlock Klasse erlaubt, dass der Block in der X, Y oder Z Axe platziert werden kann.
java
public static final Block CONDENSED_OAK_LOG = register(
"condensed_oak_log",
RotatedPillarBlock::new,
BlockBehaviour.Properties.of().sound(SoundType.WOOD),
true
);1
2
3
4
5
6
7
2
3
4
5
6
7
Säulenblöcke haben zwei Texturen, oben und an der Seite - sie verwenden das Modell block/cube_column.
Wie immer bei allen Blocktexturen befinden sich die Texturdateien in assets/example-mod/textures/block
Da der Säulenblock zwei Positionen hat, eine horizontale und eine vertikale, müssen wir zwei separate Modelldateien erstellen:
condensed_oak_log_horizontal.jsonwelche dasblock/cube_column_horizontalModell erweitert.condensed_oak_log.jsonwelche dasblock/cube_columnModell erweitert.
Ein Beispiel der Datei condensed_oak_log_horizontal.json:
json
{
"parent": "minecraft:block/cube_column_horizontal",
"textures": {
"end": "example-mod:block/condensed_oak_log_top",
"side": "example-mod:block/condensed_oak_log"
}
}1
2
3
4
5
6
7
2
3
4
5
6
7
INFO
Beachte, dass Blockzustandsdateien im Ordner assets/example-mod/blockstates zu finden sind. Der Name der Blockzustandsdatei sollte mit der Block-ID übereinstimmen, die bei der Registrierung deines Blocks in der Klasse ModBlocks verwendet wurde. Wenn die Block-ID beispielsweise condensed_oak_log lautet, sollte die Datei condensed_oak_log.json heißen.
Einen tieferen Einblick in alle Modifikatoren, die in den Blockzustand-Dateien verfügbar sind, findest du auf der Seite Minecraft Wiki - Models (Block States).
Als nächstes müssen wir eine Blockzustand-Datei erstellen. Die Blockzustand-Datei ist der Ort, an dem sich die Magie abspielt - Säulenblöcke haben drei Achsen, daher werden wir für die folgenden Situationen spezielle Modelle verwenden:
axis=x- Wenn der Block entlang der X-Achse platziert wird, drehen wir das Modell so, dass es in die positive X-Richtung zeigt.axis=y- Wenn der Block entlang der Y-Achse platziert wird, verwenden wir das normale vertikale Modell.axis=z- Wenn der Block entlang der Z-Achse platziert wird, drehen wir das Modell so, dass es in die positive X-Richtung zeigt.
json
{
"variants": {
"axis=x": {
"model": "example-mod:block/condensed_oak_log_horizontal",
"x": 90,
"y": 90
},
"axis=y": {
"model": "example-mod:block/condensed_oak_log"
},
"axis=z": {
"model": "example-mod:block/condensed_oak_log_horizontal",
"x": 90
}
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Wie immer musst du eine Übersetzung für deinen Block und ein Objektmodell erstellen, das einem der beiden Modelle übergeordnet ist.

Benutzerdefinierte Blockzustände
Benutzerdefinierte Blockzustände sind ideal, wenn dein Block einzigartige Eigenschaften hat - manchmal kannst du feststellen, dass dein Block Vanilla-Eigenschaften wiederverwenden kann.
Dieses Beispiel wird eine einzigartiges boolesche Eigenschaft mit dem Namen activated erstellen - wenn ein Spieler den Block rechtsklickt, wird der Block von activated=false zu activated=true wechseln - und seine Textur entsprechend ändern.
Die Eigenschaft erstellen
Zunächst musst du die Eigenschaft selbst erstellen - da es sich um eine boolesche Eigenschaft handelt, wird die Methode BooleanProperty.create verwendet.
java
public class PrismarineLampBlock extends Block {
public static final BooleanProperty ACTIVATED = BooleanProperty.create("activated");
}1
2
3
4
2
3
4
Als Nächstes müssen wir die Eigenschaft mit der Methode createBlockStateDefinition an den Blockzustand-Manager anhängen. Du musst die Methode überschreiben, um auf den Builder zuzugreifen:
java
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
builder.add(ACTIVATED);
}1
2
3
4
5
2
3
4
5
Außerdem musst du im Konstruktor deines benutzerdefinierten Blocks einen Standardzustand für die Eigenschaft activated festlegen.
java
public PrismarineLampBlock(Properties settings) {
super(settings);
// Set the default state of the block to be deactivated.
registerDefaultState(defaultBlockState().setValue(ACTIVATED, false));
}1
2
3
4
5
6
7
2
3
4
5
6
7
Die Eigenschaft nutzen
In diesem Beispiel wird die boolesche Eigenschaft activated umgeschaltet, wenn der Spieler mit dem Block interagiert. Hierfür können wir die Methode useWithoutItem überschreiben:
java
@Override
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hit) {
if (!player.getAbilities().mayBuild) {
// Skip if the player isn't allowed to modify the level.
return InteractionResult.PASS;
} else {
// Get the current value of the "activated" property
boolean activated = state.getValue(ACTIVATED);
// Flip the value of activated and save the new blockstate.
level.setBlockAndUpdate(pos, state.setValue(ACTIVATED, !activated));
// Play a click sound to emphasise the interaction.
level.playSound(player, pos, SoundEvents.COMPARATOR_CLICK, SoundSource.BLOCKS, 1.0F, 1.0F);
return InteractionResult.SUCCESS;
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Die Eigenschaft visualisieren
Bevor du die Blockzustand-Datei erstellst, musst du Texturen für den aktivierten und den deaktivierten Zustand des Blocks sowie für das Blockmodell bereitstellen.
Nutze dein Wissen über Blockmodelle, um zwei Modelle für den Block zu erstellen: Eines für den aktivierten Zustand und eines für den deaktivierten Zustand. Danach kannst du mit der Erstellung der Blockzustand-Datei beginnen.
Da du eine neue Eigenschaft erstellt hast, musst du die Blockzustand-Datei für den Block aktualisieren, um diese Eigenschaft zu berücksichtigen.
Wenn du mehrere Eigenschaften bei einem Block hast, musst du alle möglichen Kombinationen berücksichtigen. Zum Beispiel würden activated und axis zu 6 Kombinationen führen (zwei mögliche Werte für activated und drei mögliche Werte für axis).
Da es für diesen Block nur zwei mögliche Varianten gibt, da er nur eine Eigenschaft hat (activated), sieht der Blockzustand JSON etwa so aus:
json
{
"variants": {
"activated=false": {
"model": "example-mod:block/prismarine_lamp"
},
"activated=true": {
"model": "example-mod:block/prismarine_lamp_on"
}
}
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
TIP
Vergiss nicht ein Client Item für den Block zu erstellen, damit es im Inventar angezeigt wird!
Da es sich bei dem Beispielblock um eine Lampe handelt, müssen wir auch dafür sorgen, dass sie Licht ausstrahlt, wenn die Eigenschaft activated true ist. Dies kann über die Blockeinstellungen erfolgen, die bei der Registrierung des Blocks an den Konstruktor übergeben werden.
Du kannst die Methode lightLevel verwenden, um die vom Block ausgestrahlte Lichtstärke einzustellen. Wir können eine statische Methode in der Klasse PrismarineLampBlock erstellen, um die Lichtstärke auf der Grundlage der Eigenschaft activated zurückzugeben, und sie als Methodenreferenz an die Methode lightLevel übergeben:
java
public static int getLuminance(BlockState currentBlockState) {
// Get the value of the "activated" property.
boolean activated = currentBlockState.getValue(PrismarineLampBlock.ACTIVATED);
// Return a light level if activated = true
return activated ? 15 : 0;
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
java
public static final Block PRISMARINE_LAMP = register(
"prismarine_lamp",
PrismarineLampBlock::new,
BlockBehaviour.Properties.of()
.sound(SoundType.LANTERN)
.lightLevel(PrismarineLampBlock::getLuminance),
true
);1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
Wenn du alles vervollständigt hast, sollte das Endergebnis etwa so aussehen wie das folgende:



