Freigeben über


Einführung in das Thema Hinzufügen von Objekten

Unter Verwendung eines Verhaltenspakets und eines Ressourcenpakets kannst du ein Objekt zu Minecraft: Bedrock Edition hinzufügen. Wie du bereits in den empfohlenen Tutorials erfahren hast, kann das Verhalten von Objekten mit einem Verhaltenspaket und das Aussehen mit einem Ressourcenpaket geändert werden. Beide sind erforderlich, um dem Spiel ein funktionierendes Objekt hinzuzufügen. Diese Anleitung besteht aus zwei Teilen: Im ersten Teil geht es um die Dateien und die Ordnerstruktur, die zum Hinzufügen eines benutzerdefinierten Objekts zu Minecraft benötigt werden. Im zweiten Teil wird beschrieben, wie du dem Objekt mithilfe von Verhaltenskomponenten und Animationen Leben einhauchen kannst.

Bild eines Blauwals, das in einem Modellierungspaket erstellt wurde.

In diesem Tutorial wird Folgendes beschrieben:

  • Erstellen eines neuen benutzerdefinierten Objekts mithilfe von Verhaltens- und Ressourcenpaketen
  • Anwenden verschiedener Funktionen auf das Objekt, einschließlich Komponenten und Animationen
  • Verwenden von Übersetzungen für Namen von Objekten

Voraussetzungen

Es wird empfohlen, vor Beginn dieses Tutorials Folgendes abzuschließen:

Um diesen Artikel besser verstehen zu können, sollten darüber hinaus Kenntnisse in folgenden Bereichen vorhanden sein:

  • Funktionsweise des JSON-Formats
  • Code-Editoren wie VSCode

Dateistruktur

Im Verhaltenspaket ist eine Objektdatei für die Definition des Objekts auf der Serverseite zuständig. Im Ressourcenpaket teilt eine Client-Objektdatei dem Spiel mit, wie das Objekt aussehen wird. Die folgende Grafik zeigt, wie verschiedene Dateien interagieren können, um ein benutzerdefiniertes Objekt zu erstellen:

Beziehungen zwischen Ressourcenpaketen und Verhaltenspaketen

Beispiel für ein Roboter-Objekt– min robot

Damit du einen Anhaltspunkt für dieses Tutorial hast, stellen wir zwei Versionen desselben Objekts zur Verfügung: eines Roboters, der beliebig in der Welt spawnen kann und drei zufällige Texturen, eine Radanimation, verschiedene Komponenten und eine benutzerdefinierte Wassermechanik aufweist. Der Download-Link ist im Abschnitt Voraussetzungen oben zu finden.

Um den Roboter in Aktion zu erleben, wähle eines der Ressourcen- und Verhaltenspakete aus, die du soeben heruntergeladen hast. (Wir empfehlen, zunächst einmal die Minimumversion auszuprobieren. Stelle die Ressourcen- und Verhaltenspakete in ihre jeweiligen Unterordner von com.mojang, starte eine Welt mit aktivierten Cheats und verwende /summon compass:robot.

Dies ist die Struktur des fertigen Verhaltenspakets und Ressourcenpakets für „minimum robot“:

Dateistruktur eines fertigen „minimum robot“-Objekts

Das sieht ziemlich umfangreich aus, aber du musst dir nur Gedanken über die Dateien mit „robot“ in ihrem Namen und über ihren Speicherort machen.

Nachdem du eine Vorstellung davon bekommen hast, wie sich der Roboter im Spiel verhält, kannst du die fertigen Ressourcen- und Verhaltenspakete für den Roboter entfernen und sie unter Berücksichtigung der in diesem Tutorial beschriebenen Schritte von Grund auf neu erstellen. So kannst du dir ein Bild davon machen, wie alle diese Dateien zusammenwirken.

Als Ausgangspunkt würden sich die in den früheren Tutorials erstellten Ressourcen- und Verhaltenspakete eignen. Vielleicht möchtest du das Objekt der angriffslustigen Kuh entfernen, aber das ist eine persönliche Vorliebe.

Benennung

Beim Erstellen eines Objekts solltest du dir zunächst überlegen, welche ID du dem Objekt geben möchtest. Die Dateien in deinen Ressourcen- und Verhaltenspaketen müssen unter Verwendung der Objekt-ID, die du deinem Objekt gibst, synchronisiert werden. Diese ID besteht aus einem Namespace und einem Namen, getrennt durch einen Doppelpunkt. Wir haben diese ID– compass:robot– zuvor verwendet, um den Roboter in die Welt zu holen.

Für deinen eigenen Namespace kannst du eine Kurzversion deines Team- oder Produktnamens verwenden. Die ID sollte nur Kleinbuchstaben, Ziffern und Unterstriche enthalten. Verwende nicht „minecraft“ als Namespace für benutzerdefinierte Inhalte. Der Namespace „minecraft“ ist für Vanilla-Ressourcen reserviert. Daher solltest du „minecraft“ nur verwenden, wenn du Vanilla-Inhalte überschreibst.

Die meisten Dateien, die das Objekt definieren, werden JSON-Dateien sein. Um Verwechslungen zu vermeiden, wird empfohlen, beim Erstellen dieser Dateien eine erweiterte Dateierweiterung zu verwenden. In den meisten Fällen werden Dateinamen vom Spiel ignoriert. Während der Arbeit an einem Add-On können unklare Dateinamen jedoch für Verwirrung sorgen. Die Erweiterungen lauten wie folgt:

Dateityp Dateiname
Client-Objektdateien entity_name.entity.json
Modelldateien entity_name.geo.json
Animationsdateien entity_name.animation.json
Animationscontroller entity_name.animation_controllers.json
Render-Controller entity_name.render_controllers.json

entity_name sollte durch den Namen deines Objekts ersetzt werden, ohne den Namespace.

Formatversionen

Jede JSON-Datei sollte ein format_version-Tag haben. Dieses Tag ist wichtig, damit das Spiel die Datei korrekt lesen kann. Es ist wichtig, zu wissen, dass in älteren Formaten erstellte Dateien auch in neueren Versionen des Spiels weiterhin funktionieren. Dies gilt jedoch nur, wenn die Formatversion korrekt eingestellt ist. Inkorrekte Formatversionen sind eine häufige Fehlerquelle.

Verhaltenspaket-Definition

Der erste praktische Schritt, um dem Spiel einen Roboter hinzuzufügen, beginnt im Verhaltenspaket. Erstelle eine neue Datei im Ordner entities des Verhaltenspakets und nenne diese robot.json. Kopiere diesen Code und füge ihn ein.

{
    "format_version": "1.12.0",
    "minecraft:entity": {
        "description": {
            "identifier": "compass:robot",
            "is_spawnable": true,
            "is_summonable": true
        },
        "components": {}
    }
}

Innerhalb des Beschreibungs-Tags definieren wir grundlegende Attribute des Objekts. identifier legt die ID für das Objekt fest. is_spawnable fügt später ein Spawn-Ei in das Spiel ein, mit dem der Spieler diese Kreatur spawnen kann. is_summonable lässt das Objekt mit dem Befehl /summon arbeiten.

Innerhalb von components werden wir Komponenten hinzufügen, um das Verhalten des Objekts zu ändern. Im Augenblick fügen wir nur die Komponente minecraft:physics hinzu. Dadurch erhält das Objekt Schwerkraft- und reguläres Kollisionsverhalten.

"components": {
    "minecraft:physics": {}
}

Speichere deine Datei robot.json und fahre mit dem nächsten Schritt fort.

Client-Objekt-Definition

Jetzt müssen wir das Objekt dem Ressourcenpaket hinzufügen, um ihm ein visuelles Erscheinungsbild zu geben. Erstelle im Ordner entity des Ressourcenpakets eine neue JSON-Datei mit dem Namen robot.entity.json.

{
    "format_version": "1.10.0",
    "minecraft:client_entity": {
        "description": {
            "identifier": "compass:robot",
            "spawn_egg": {
                "base_color": "#505152",
                "overlay_color": "#3b9dff"
            }
        }
    }
}

Dies ist die Grundstruktur der Datei. Bisher ist sie ähnlich wie bei der verhaltensseitigen Datei, die wir im vorherigen Abschnitt erstellt haben. Beachte, dass wir jetzt client_entity und nicht nur „entity“ verwenden. Zum Zeitpunkt der Veröffentlichung dieses Artikels ist 1.10.0 die aktuelle Formatversion für diese Datei.

Das spawn_egg-Tag definiert, wie das Spawn-Ei im Inventar aussehen wird. Mit diesem Verfahren sieht es aus wie ein Vanilla-Spawn-Ei, jedoch mit benutzerdefinierten Farben.

Visuelle Elemente

Bevor wir das Objekt in das Spiel aufnehmen können, benötigen wir ein Modell. Im Artikel Objektmodellierung und -animation wird beschrieben, wie ein benutzerdefiniertes Modell und eine benutzerdefinierte Textur erstellt werden können. Das Erstellen eines Modells erfordert jedoch umfangreiche Kenntnisse und wir haben dieses Tutorial noch nicht abgeschlossen. Du kannst also vorerst so tun, als hättest du bereits ein Modell erstellt, indem du die Dateien aus dem Roboter-Ressourcenpaket kopierst und einfügst. Führe später dieselben Schritte aus, um das von dir erstellte Modell hinzuzufügen.

  • Speichere das Modell im Ordner models/entity als robot.geo.json.
  • Speichere die Textur in textures/entity als robot.png.

Nachdem nun die Modelldateien vorhanden sind, benötigen wir einen Render-Controller, um das Modell, die Textur und den Werkstoff, die für das Objekt verwendet werden, zu verknüpfen.

Öffne die Datei robot.entity.json im Ordner entity in deinem Ressourcenpaket.

Für die meisten Objekte (wie z.B. unseren Roboter) können wir den Standard-Render-Controller verwenden, der vom Spiel bereitgestellt wird. Später im fortgeschrittenen Teil dieses Tutorials werden wir noch mehr über Render-Controller sprechen. Im Moment genügt es, wenn du weißt, dass es so funktioniert und dass der Inhalt wie folgt lauten sollte:

{
    "format_version": "1.10.0",
    "minecraft:client_entity": {
        "description": {
            "identifier": "compass:robot",
            "materials": {
                "default": "entity"
            },
            "textures": {
                "default": "textures/entity/robot"
            },
            "geometry": {
                "default": "geometry.robot"
            },
            "render_controllers": [
                "controller.render.default"
            ],
            "spawn_egg": {
                "base_color": "#505152",
                "overlay_color": "#3b9dff"
            }
        }
    }
}

Auf das Modell wird durch den Geometrienamen verwiesen. Wenn du ein Modell in Blockbench erstellst, achte darauf, dass der Geometriename in den Projekteinstellungen auf deinen Objektnamen festgelegt ist. In diesem Fall ist dies „Robot“.

Im Gegensatz zu Geometrien werden Texturen durch ihren Pfad im Ressourcenpaket ohne die Dateierweiterung verknüpft, wie im Beispiel gezeigt.

In den meisten Fällen ist kein benutzerdefinierter Werkstoff erforderlich. Stattdessen kannst du einen Standardwerkstoff verwenden. In diesem Beispiel verwenden wir entity. Wenn die Textur transparente Teile hat, kannst du entity_alphatest verwenden. Wenn die Textur durchscheinend ist (wie beispielsweise gefärbtes Glas), kannst du entity_alphablend verwenden.

Übersetzungszeichenfolgen

Derzeit hat weder das Objekt selbst noch das Spawn-Ei einen richtigen Namen im Spiel. Um einen Namen zu definieren, benötigen wir eine Sprachdatei. Erstelle einen neuen Ordner mit dem Namen texts in deinem Ressourcenpaket und eine neue Datei mit dem Namen en_US.lang. Für benutzerdefinierte Objekte müssen wir nur diese Sprachdatei ändern, da alle anderen Sprachen standardmäßig amerikanisches Englisch verwenden. Füge in dieser Datei die folgenden beiden Zeilen hinzu:

entity.compass:robot.name=Robot
item.spawn_egg.entity.compass:robot.name=Spawn Robot

Die erste Zeile definiert den Namen des Objekts. Dieser wird in Todesmeldungen und in der Ausgabe einiger Befehle sichtbar sein. Schlüssel und Wert sind stets durch ein Gleichheitszeichen getrennt. Die erste Zeile kann unterteilt werden in:

entity.<identifier>.name=<Name>

Die zweite Zeile definiert den Gegenstandsnamen des Spawn-Eis:

item.spawn_egg.entity.<identifier>.name=<Name>

Testen

Denke daran, dass du das Ganze frühzeitig und immer wieder testen solltest. Wenn du frühzeitig auf ein Problem stößt, kannst du diesem leichter nachgehen und es möglicherweise beheben. Wenn du häufig testest, wirst du schon kurz nach vorgenommenen Änderungen auf Probleme aufmerksam. Dies macht es einfacher, die Fehlerursachen auf die zuletzt vorgenommenen Änderungen einzugrenzen.

Du solltest in der Lage sein, dein Objekt im Spiel mit dem Spawn-Ei oder dem Aufrufbefehl zu spawnen. Wenn du nur ein statisches Objekt haben willst, kannst du schon loslegen. Wenn du das Objekt noch weiter anpassen möchtest, lies hier weiter.

Beispiel für ein Roboter-Objekt– full robot

Jetzt wäre ein guter Zeitpunkt, um die Ressourcen- und Verhaltenspakete für den full robot auszuprobieren. Vergleiche die Sammlung von Ordnern und Dateien. Stelle dann die Pakete für den „minimal robot“ zurück, damit wir weitere Funktionalität hinzufügen können.

Komponenten

Komponenten teilen dem Objekt mit, wie es sich im Spiel verhalten soll. Wir werden nun einige Komponenten hinzufügen und im Detail erläutern, was diese tun.

Öffne im Ordner behavior pack/entities/ die Datei robot.json und ersetze den einzelnen Eintrag "minecraft:physics": {} durch den gesamten folgenden Text:

   "components": {
        "minecraft:physics": {},
        "minecraft:nameable": {},
        "minecraft:movement": {
            "value": 0.25
        },
        "minecraft:movement.basic": {},
        "minecraft:jump.static": {},
        "minecraft:navigation.walk": {
            "avoid_water": true
        },
        "minecraft:behavior.tempt": {
            "priority": 1,
            "speed_multiplier": 1.4,
            "items": ["diamond"],
            "within_radius": 7.0
        },
        "minecraft:behavior.random_stroll":
        {
            "priority": 3,
            "speed_multiplier": 0.8
        },
        "minecraft:experience_reward": {
            "on_death": 8
        }
   }
Komponentenname Beschreibung
minecraft:nameable Ermöglicht dem Spieler, das Objekt mit einem Namens-Tag zu benennen.
minecraft:movement Teilt dem Objekt mit, wie schnell es sich bewegen soll. 0,25 ist die reguläre Geschwindigkeit der meisten Tiere in Minecraft.
minecraft:movement.basic Verleiht dem Objekt die Fähigkeit, sich auf dem Boden zu bewegen.
minecraft:jump.static Ermöglicht dem Objekt, zu springen, um Blöcke zu besteigen.
minecraft:navigation.walk Ermöglicht dem Objekt, durch die Welt zu navigieren. Das Vermeiden von Wasser ist eine der Optionen zu dieser Komponente.
minecraft:behavior.tempt Lässt das Objekt Spielern folgen, die Diamanten in der Hand halten. Wir geben diesem Verhalten eine höhere Priorität, damit diese Aktion priorisiert wird (niedrigere Zahl = höhere Priorität).
minecraft:behavior.random_stroll Lässt das Objekt zufällig am Ort herumlaufen. Wir setzen die Priorität auf einen höheren Wert, damit das Objekt dies nur tut, wenn es nichts anderes zu tun hat. Der Geschwindigkeitsmultiplikator verringert die Geschwindigkeit bei Verwendung dieses Gehverhaltens.
minecraft:experience_reward Löst einen Erfahrungs-Drop des Objekts aus, wenn es von einem Spieler getötet wird.

Animationen

In diesem Abschnitt fügen wir dem Roboter lediglich eine einfache Rad-Animation hinzu. Wenn du mehr über Animationen, die Verwendung von Animationscontrollern und das Erstellen von Animationen in Blockbench erfahren möchtest, lies diese Anleitung.

Animationen werden in Animationsdateien gespeichert. Wir müssen also zuerst einen Ordner mit dem Namen animations im Ressourcenpaket und darin eine Datei mit dem Namen robot.animation.json erstellen. In dieser Datei erstellen wir eine neue Animation mit dem Namen animation.robot.drive. Wir setzen außerdem loop auf true, damit die Animation weiter abgespielt wird. Die Datei sollte wie folgt aussehen:

{
    "format_version": "1.8.0",
    "animations": {
        "animation.robot.drive": {
            "loop": true
        }
    }
}

Animationen ermöglichen uns, die Position, Drehung und Skalierung jedes Knochens zu animieren. (Wenn du nicht weißt, was „Knochen“ in diesem Zusammenhang bedeutet, ist das in Ordnung. Wenn du dich mit Blockbench beschäftigst, wirst du mehr über Knochen erfahren. Im Augenblick musst du nur wissen, dass damit ein Chunk des Modells, beispielsweise ein Bein oder ein Rad gemeint ist.) Animationen können mit Keyframes und/oder Molang-Ausdrücken durchgeführt werden. In diesem Beispiel verwenden wir nur Molang-Ausdrücke.

MoLang ist eine Sprache speziell für Ressourcen- und Verhaltenspakete. Damit können wir verschiedene Zahlen aus den Objekt mit einer Abfrage erhalten und mithilfe mathematischer Ausdrücke daraus ein Ergebnis berechnen. Beispielsweise gibt die Abfrage query.modified_distance_moved den Abstand aus, um den das Objekt verschoben wurde. Wir können damit die Rotation des Roboterrads auf der X-Achse berechnen. Dies führt zu einer Animation, die den Roboter so aussehen lässt, als würde er fahren. Du musst ein wenig mit diesen Zahlen herumspielen. Für dieses Modell funktioniert 60 aber ganz gut.

{
    "format_version": "1.8.0",
    "animations": {
        "animation.robot.drive": {
            "loop": true,
            "bones": {
                "wheel": {
                    "rotation":["query.modified_distance_moved*60", 0, 0]
                }
            }
        }
    }
}

Nachdem die Animation erstellt wurde, müssen wir sie in der Client-Objektdatei verknüpfen. (Denk daran: Das Ressourcenpaket ist der Client, öffne also <resource pack>/entity/robot.entity.json für diesen nächsten Teil.) Das Tag animations verknüpft alle Animationen und Animationscontroller, die von dem Objekt verwendet werden. Jede Animation erhält einen Kurznamen, mit dem die Animation in einem Animationscontroller oder direkt in der Datei– in diesem fall drive – wiedergegeben werden kann.

Die Abschnitte scripts und animate können verwendet werden, um Animationen direkt abzuspielen:

        "animations": {
            "drive": "animation.robot.drive"
        },
        "scripts": {
            "animate": ["drive"]
        }

Wenn diese beiden Tags im Beschreibungs-Tag der Client-Objektdatei hinzugefügt wurden, ist die Drive-Animation immer aktiv und setzt die Raddrehung fort, während sich das Objekt bewegt.

Render-Controller

Mit Render-Controllern können wir die Geometrie, Texturen und Werkstoffe des Objekts mithilfe von MoLang ändern. Im folgenden Beispiel wird gezeigt, wie die Geometrie, der Werkstoff und die Textur, die in der Client-Objektdatei als default verknüpft sind, verwendet werden:

{
    "format_version": "1.8.0",
    "render_controllers": {
        "controller.render.robot": {
            "geometry": "Geometry.default",
            "materials": [ { "*": "Material.default" }],
            "textures": [ "Texture.default" ]
        }
    }
}

Wenn wir nur eine Standardgeometrie, einen Standardwerkstoff und eine Standardtextur verwenden möchten, können wir sie einfach so belassen, dass sie wie zuvor auf den Standard-Render-Controller verweisen. Dies ist jedoch ein guter Zeitpunkt, um zu lernen, wie zufällige Texturen hinzugefügt werden. Sehen wir uns also etwas genauer an, wie Render-Controller arbeiten.

Render-Controller– Erläuterung

Du wirst feststellen, dass das Basis-Tag den Namen render_controllers hat. Dies bedeutet, dass wir mehrere Render-Controller in einer Datei angeben können.

Unser Render-Controller wird nach folgendem Schema benannt: controller.render.<entity_name>. Für einen Mehrzweck-Render-Controller können wir anstelle des Objektnamens auch ein anderes Schlüsselwort verwenden.

Innerhalb des Render-Controller-Tags werden die verschiedenen Ressourcen angegeben. Du wirst jedoch feststellen, dass jede davon ein anderes JSON-Format verwendet.

Geometrie

Ein Render-Controller kann immer nur eine Geometrie anzeigen. Deshalb ist er direkt als eine Zeichenfolge verknüpft. Diese Zeichenfolge kann ein Molang-Ausdruck sein und sollte immer eine Geometrie zurückgeben. In diesem Fall wird Geometry.default aufgerufen. Dies bedeutet, dass die Geometrie zurückgegeben wird, die als default mit dem Objekt verknüpft ist, das den Render-Controller verwendet.

Du kannst mehrere Geometrien auf einem Objekt rendern, wenn du mehrere Render-Controller verwendest. Dies kann jedoch schwierig sein und zu unerwartetem Verhalten führen. Daher ist dies nur für erfahrene Ersteller zu empfehlen.

Werkstoffe

Im Gegensatz zur Geometrie werden Werkstoffe als Array von Objekten geschrieben. Dabei geht es darum, dass wir jedem Knochen einen eigenen Werkstoff zuweisen können. Jedes Objekt im Array kann ein Schlüssel-Wert-Paar haben. Der Schlüssel wählt einen Satz von Knochen aus. Ein Sternchen wird als Platzhalter verwendet. Dies bedeutet, dass allen Knochen unabhängig vom Namen der Standardwerkstoff zugewiesen wird. Beachte, dass Werkstoffe in der angegebenen Reihenfolge zugewiesen werden. Dies bedeutet, dass Werkstoffe weiter unten in der Liste vorherige Werkstoffe überschreiben können.

        "materials": [
            { "*": "Material.default" },
            { "*_arm": "Material.transparent" }
        ],

In diesem Beispiel wenden wir zunächst den Standardwerkstoff auf alle Knochen an. Dann überschreiben wir den Werkstoff mit dem transparenten Werkstoff auf allen Knochen, die mit _arm enden. Auf diese Weise unterstützen alle Armknochen Transparenz.

Texturen

Texturen werden in einem Array angegeben. In den meisten Fällen wird hier nur eine Textur verknüpft, da Objekte keine separaten Texturen unterstützen. Es gibt jedoch eine Ausnahme: Werkstoffe können mehrere übereinander geschichtete Texturen unterstützen, z.B. den Werkstoff entity_multitexture. Dies wird beispielsweise von Lamas verwendet, um die Kulisse zu überlagern.

Arrays

Bei der Arbeit mit mehreren Ressourcen eines Typs kann es nützlich sein, ein Array zu verwenden. Ein Array ist eine Liste von Ressourcenlinks, die im Render-Controller definiert sind und die du mithilfe von MoLang auswählen kannst.

Wir können ein Array für den Roboter wie folgt definieren:

        "controller.render.robot": {
            "arrays": {
                "textures": {
                    "Array.variant":[
                        "Texture.default",
                        "Texture.variant_b",
                        "Texture.variant_c"
                    ]
                }
            },

Im Arrays-Abschnitt können wir Arrays für jede der drei Kategorien definieren: textures, materials und geometries. Innerhalb der Kategorie kannst du Arrays mit Array.<array name> als Name definieren. Jede Zeile innerhalb des Arrays verknüpft eine Textur, die in der Client-Objektdatei definiert ist.

Du kannst über MoLang auf das Array zugreifen. Arrays sind 0-basiert, sodass die erste Textur in diesem Array über Array.variant[0] aufgerufen werden kann.

In diesem Beispiel verwenden wir die Variantenabfrage, um eine Textur aus dem Array auszuwählen. Die Variante einer Kreatur kann über die Komponente minecraft:variant in der Verhaltensdatei geändert werden.

"textures": [ "Array.variant[ query.variant ]" ]

Jetzt müssen wir die zusätzlichen Texturen in der Client-Objektdatei verknüpfen. Die reguläre, blaue Robotertextur ist bereits als default verknüpft. Wir erstellen jetzt zwei Kopien der Robotertexturdatei, bearbeiten die Farbe und verknüpfen sie als variant_b und variant_c.

            "textures": {
                "default": "textures/entity/robot",
                "variant_b": "textures/entity/robot_b",
                "variant_c": "textures/entity/robot_c"
            },

Jetzt sind die Texturen verknüpft. Der letzte Schritt besteht darin, die Variante in der Verhaltensdatei zu randomisieren. Wir verwenden dafür Komponentengruppen. Mit diesem kann dem Objekt jederzeit ein Satz von Komponenten hinzugefügt bzw. daraus entfernt werden. Weiterhin verwenden wir ein Ereignis, das zufällig festlegt, welche Komponentengruppe hinzugefügt werden soll.

        "description": {
            ...
        },
        "components": {
            ...
        },
        "component_groups": {
            "compass:color_0": {
                "minecraft:variant": {"value": 0}
            },
            "compass:color_1": {
                "minecraft:variant": {"value": 1}
            },
            "compass:color_2": {
                "minecraft:variant": {"value": 2}
            }
        },
        "events": {
            "minecraft:entity_spawned": {
                "randomize": [
                    {
                        "add": {
                            "component_groups": ["compass:color_0"]
                        }
                    }, {
                        "add": {
                            "component_groups": ["compass:color_1"]
                        }
                    }, {
                        "add": {
                            "component_groups": ["compass:color_2"]
                        }
                    }
                ]
            }
        }

Wenn wir jetzt das Objekt zum ersten Mal spawnen, wird zufällig eine Komponentengruppe und damit eine Variante ausgewählt. Dies ist eine sehr verbreitete Technik, um das Aussehen eines Objekts zu randomisieren.

Spawning

Spawn-Regeln legen fest, wie Objekte zufällig in der Welt gespawnt werden. Wir erstellen eine Spawn-Regeldatei für unseren Roboter. Erstelle zunächst einen Ordner mit dem Namen spawn_rules in deinem Verhaltenspaket. Erstelle in diesem Ordner eine neue Textdatei mit dem Namen robot.json. Der Inhalt der Datei sollte wie folgt aussehen:

{
    "format_version": "1.8.0",
    "minecraft:spawn_rules": {
        "description": {
            "identifier": "compass:robot",
            "population_control": "animal"
        },
        "conditions": []
    }
}

In minecraft:spawn_rules gibt es zwei Dinge für uns zu beachten: population control (Populationskontrolle) und conditions(Bedingungen).

description definiert die grundlegenden Eigenschaften der Datei. identifier muss mit dem Bezeichner unseres Objekts übereinstimmen. population_control definiert, wie das Spiel weiß, wie viele Kreaturen gespawnt werden müssen. Dies ist ein bisschen komplizierter.

Populationskontrolle

Es gibt verschiedene Pools von Objekten. Wenn der hier definierte Pool als voll gilt, wird das Spiel keine Kreaturen aus diesem Pool mehr spawnen. Es gibt drei verschiedene Optionen:

  • „animal“: Passive Kreaturen wie Kühe oder Schweine
  • „water_animal“: Wasser-Kreaturen wie Tropenfische oder Delfine
  • „monster": Feindselige Kreaturen wie Skelette oder Zombies

Für den Roboter nutzen wir den „animal“-Pool.

Bedingungen

conditions ist ein Array möglicher Bedingungen, die es einer Kreatur ermöglichen, in der Welt gespawnt zu werden. Jede der Bedingungen versucht separat, Kreaturen in der Welt zu spawnen. Jede davon besteht aus einer Gruppe von Komponenten, die festlegen, wann eine Kreatur gespawnt werden soll und wann nicht.

Für eine grundlegende Spawning-Regel reicht eine Bedingung aus. Für den Roboter verwenden wir diese Konfiguration:

{
    "format_version": "1.8.0",
    "minecraft:spawn_rules": {
        "description": {
            "identifier": "compass:robot",
            "population_control": "animal"
        },
        "conditions": [
            {
                "minecraft:spawns_on_surface": {},
                "minecraft:brightness_filter": {
                    "min": 12,
                    "max": 15,
                    "adjust_for_weather": false
                },
                "minecraft:weight": {
                    "default": 40
                },
                "minecraft:biome_filter": {
                    "test": "has_biome_tag",
                    "value": "animal"
                }
            }
        ]
    }
}
Komponentenname Beschreibung
minecraft:spawns_on_surface Die Kreatur wird an der Oberfläche gespawnt.
minecraft:brightness_filter Das Objekt wird nur bei einer bestimmten Helligkeit gespawnt. Akzeptiert drei Optionen: min, max und adjust_for_weather. Die Lichtstärke reicht von 0 bis 15. Ist adjust_for_weather auf true gesetzt, wird die Lichtstärkeabnahme durch Regen und Gewitter berücksichtigt.
minecraft:weight Die Gewichtung des Objekts beim Spawnen. Je höher die Zahl, desto häufiger wird die Kreatur gespawnt.
minecraft:biome_filter Filtert das Biom, in dem die Kreatur gespawnt werden darf. Biom-Filter funktionieren ähnlich wie Verhaltensfilter. Dies bedeutet, dass Operatoren wie all_of und any_of erlaubt sind. Biome haben verschiedene Tags, die den Biomtyp, die Variante, die Dimension und Merkmale wie „Monster“ oder „Tier“ angeben.

Roboter werden jetzt überall an der Oberfläche gespawnt, wo Tiere gespawnt werden können und wo ausreichend Licht vorhanden ist. Mit einer Gewichtung von 40 werden sie auch ziemlich häufig gespawnt.

Verhaltensanimationen

Verhaltensanimationen funktionieren ähnlich wie normale Animationen, werden jedoch im Verhaltenspaket ausgeführt. Während reguläre Animationen die Bewegung des Modells sowie Sounds und Partikel animieren, können Verhaltensanimationen reguläre Befehle ausführen, Objektereignisse auslösen oder MoLang-Ausdrücke ausführen. Verhaltensanimationen werden oft auch als Objektereignisse bezeichnet, obwohl dieser Name tendenziell etwas irreführend ist.

Da Roboter kein Wasser mögen, fügen wir eine Mechanik hinzu, durch die Roboter in Wasser oder Regen beschädigt werden. Zunächst erstellen wir einen Animationscontroller, um mithilfe einer MoLang-Abfrage zu testen, wann sich das Objekt im Wasser befindet. Erstelle einen neuen Ordner im Verhaltenspaket mit dem Namen animation_controllers und dann darin die Datei robot.animation_controllers.json:

{
    "format_version": "1.10.0",
    "animation_controllers": {
        "controller.animation.robot.in_water": {
            "states": {
                "default": {
                    "transitions": [
                        {"in_water": "query.is_in_water_or_rain"}
                    ]
                },
                "in_water": {
                    "transitions": [
                       {"default": "query.is_in_water_or_rain == 0"}
                    ]
                }
            }
        }
    }
}

Der Animationscontroller sieht normalen clientseitigen Animationscontrollern sehr ähnlich. Er hat zwei Status, die gewechselt werden, je nachdem, ob sich der Roboter im Wasser befindet oder nicht.

Fügen wir jetzt eine Animation hinzu, die einen Vergiftungseffekt für den Roboter beinhaltet. Erstelle den Ordner animations im Verhaltenspaket und dann eine Datei mit dem Namen robot.animation.json:

{
    "format_version": "1.8.0",
    "animations": {
        "animation.robot.poison": {
            "loop": true,
            "animation_length": 1,
            "timeline": {
                "0.0": [
                    "/effect @s poison 2 0 true"
                ]
            }
        }
    }
}

Anstelle des Knochen-Tags zum Animieren von Knochen verwenden wir das Timeline-Tag. In Ressourcenpaketen können Timelines nur zum Ausführen von MoLang-Code verwendet werden. In Verhaltensanimationen kannst du damit MoLang-Code und Befehle ausführen oder Objektereignisse auslösen. Beachte, dass sie alle als Zeichenfolge bereitgestellt werden. Das Spiel erkennt den Typ der Zeichenfolge an ihrem Inhalt. Wenn die Zeichenfolge mit einem Schrägstrich beginnt, wird sie als Befehl ausgeführt. Wenn sie dem Schema @s namespace:event entspricht, wird sie als Objektereignis ausgeführt. Wenn sie wie MoLang aussieht, wird sie als MoLang ausgeführt.

Aus diesem Grund ist es wichtig, Befehle in Verhaltensanimationen mit einem Schrägstrich zu beginnen. Beachte außerdem, dass wir Gift für zwei Sekunden anwenden, da eine Sekunde nicht ausreichen würde, um tatsächlich Schaden anzurichten. Durch das true am Ende des Befehls wird der Statuseffekt zur Umgebung. Dies bedeutet, dass keine Partikel entstehen.

Wie bei Animationen in Ressourcenpaketen müssen wir alle unsere Animationen und Animationscontroller im Beschreibungs-Tag unseres Objekts verknüpfen. Dies wird wie folgt aussehen:

        "description": {
            "identifier": "compass:robot",
            "is_spawnable": true,
            "is_summonable": true,
            "animations": {
                "poison": "animation.robot.poison",
                "in_water": "controller.animation.robot.in_water"
            },
            "scripts": {
                "animate": [
                    "in_water"
                ]
            }
        },

Im Abschnitt zu Animationen werden alle Animationen und Animationscontroller, die vom Objekt verwendet werden, mit einem Kurznamen aufgeführt. Im Abschnitt „scripts/animate“ listen wir die Animationen auf, die immer ausgeführt werden sollen. Wir möchten, dass der Controller den Status für dauerhafte Ausführung erkennt, nicht jedoch den Vergiftungseffekt.

Jetzt müssen wir zum Animationscontroller zurückkehren und den Vergiftungseffekt hinzufügen. Wir werden auch eine kleine Regenerationsmechanik zusammen mit einem Soundeffekt hinzufügen, damit der Roboter nicht so leicht stirbt.

            "states": {
                "default": {
                    "transitions": [
                        {"in_water": "query.is_in_water_or_rain"}
                    ]
                },
                "in_water": {
                    "animations": [
                        "poison"
                    ],
                    "on_exit": [
                        "/effect @s regeneration 2 4 true",
                        "/playsound random.fizz @a[r=16]"
                    ],
                    "transitions": [
                        {"default": "query.is_in_water_or_rain == 0"}
                    ]
                }
            }

Im animations-Array listen wir alle Animationen auf, die in diesem Status ausgeführt werden sollen. In unserem Fall ist dies nur poison.

Im on_exit-Tag fügen wir zwei Befehle hinzu, die ausgeführt werden, wenn der Roboter das Wasser verlässt. Der erste Befehl gibt dem Roboter zwei Sekunden lang einen Regenerationseffekt der Stufe vier. Der zweite Befehl spielt einen zischenden Soundeffekt ab.

Beachte, dass wir den Befehl auch im on_entry-Array des Standardstatus hätten ausführen können. Dadurch wären die Effekte jedoch auch beim Spawnen des Roboters oder beim Neuladen der Welt wiedergegeben worden, da das Spiel immer zuerst in den Status default übergeht.

Um die Beziehung zwischen Controllern und Animationen zusammenzufassen: Ein Animationscontroller wird verwendet, um zu steuern, wann eine Animation wiedergegeben wird. Eine Animation selbst ist das, was als Ergebnis des Übergangs zur Animation erfolgt, wie vom Controller festgelegt. Animationen und Animationscontroller werden für die Objektverhaltensdatei bereitgestellt.

Wie geht es weiter?

In dieser Anleitung haben wir dem Spiel eine vollständiges benutzerdefiniertes Objekt hinzugefügt. Wenn du die vorhandenen Modelldateien verwendet hast, anstatt eigene zu erstellen, ist jetzt vielleicht ein guter Zeitpunkt, um mehr über Blockbench zu erfahren. Du kannst dich auch eingehender mit dem Objektverhalten für den Server befassen.