この記事は、Minecraftサーバ開発・運営 Advent Calendar 2021 7日目です。
この記事はリソースパックのみ触れます。
behavior packの作り方は各自で調べてください。
また、pmmpサーバー向けの解説です。
まず.objファイル、.mtlファイルを用意します。AI生成などで制作してください。
軽量化
ブレンダーをダウンロードします。
https://www.blender.org/download/
ポータブル版などを使用しましょう。
シーンコレクションから、Cubeを選択し、deleteして削除します。

「比率」を軽量化したい分だけ下げます。変更するとブレンダーがフリーズしますが異常ではありません。
軽量化でモデルの破綻が起きていないことがわかったら、次に進みます。
ポリゴン数を下げないと、この後行うブロックベンチでの変換でブロックベンチがクラッシュします。
ブレンダーを閉じます。
変換
ブロックベンチ、可能であればexe版をダウンロードします。
このセクションは必須です!
プラグインマーケットプレイスを開きます。
meshyと検索します。
meshy
プラグインウィザードを閉じます。
Bedrock Entityをクリックします。
新規モデルをクリックします。
このウィザードでは、prefaceuv、テクスチャサイズは付属の画像に依存、Model Identifierは任意の名前で作成します(geometryを付与してますがこれは間違いです。)

FIle > Import > Import OBJ Modelで軽量化したモデルをインポートします。
Import OBJ Modelがない場合は、meshyプラグインをインストールできていません。
読み飛ばさないでください。
スケールは4か8か16にし、Confirmを押して1分待ちます。
モデルが巨大すぎる場合ブロックベンチがクラッシュします

ブロックベンチがクラッシュした場合、次の原因が考えられます
- objファイルがでかすぎる
- スケールが大きい
- 間違って軽量化前のモデルを読み込んだ
フォルダボタンでフォルダを作成し、フォルダをダブルクリックして名前をbodyにします。

マウスドラッグでbodyの入れ子にします
(このときコピペは使わないでください。ブロックベンチがクラッシュします。)

モデルの位置を地面に合わせて調整してください。
動作が不安定になる可能性がありますが、そのまま調整を行ってください。スペースキーで移動モードを切り替えられます。
モデルのクリック(クラッシュするかもしれません)し、モデルの向きを、Nと書いてある方向に回転させます。

File > Export > Exprot Bedrock Geometryでエクスポートします。
リソースパック化
manifestジェネレーターを開きます。
ダウンロードします。
リソースパックのルートに置きます。
models\entityフォルダを作成します(o models x model)
先ほどのモデルファイルを置きます。
textures\entity\<任意の名前>\フォルダを作成します。
3ds\textures\entity\yuusilya\fantasycharacter3dmodel_basecolor.JPEGなどのように、テクスチャを置きます。
entityフォルダを作成します。
中身に<任意の名前>.jsonを作成し、
中身のsod:yuusilyaを任意のものに変更し、
geometry.dragonを、モデルの識別子と一致させます。
また、 "default": "textures/entity/yuusilya/fantasycharacter3dmodel_basecolor.JPEG"は正しいテクスチャを指すように修正します。
モデルの識別子とはモデルファイルの先頭に書かれているモデルidのことです。
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.yusilya", //これ!!!
"texture_width": 4096,
"texture_height": 4096,
"visible_bounds_width": 1,
"visible_bounds_height": 1,
"visible_bounds_offset": [0, 0, 0]
},
"bones": [
{
"name": "body",
"pivot": [0, 0, 0],
"poly_mesh": {
3ds\entity\yuusilya.json
{
"format_version": "1.10.0",
"minecraft:client_entity": {
"description": {
"identifier": "sod:yuusilya",
"min_engine_version": "1.8.0",
"materials": {
"default": "entity_alphatest"
},
"textures": {
"default": "textures/entity/yuusilya/fantasycharacter3dmodel_basecolor.JPEG"
},
"geometry": {
"default": "geometry.yusilya"
},
"render_controllers": [ "controller.render.commonr" ]
}
}
}
render_controllersを作成します。
controller.render.commonr.jsonを作成します。
中身を次のようにします。
3ds\render_controllers\controller.render.commonr.json
{
"format_version": "1.10.0",
"render_controllers": {
"controller.render.commonr": {
"geometry": "geometry.default",
"materials": [
{
"*": "material.default"
}
],
"textures": ["texture.default"]
}
}
}
すべて完了したら、7zipなどでmanifest.jsonがrootに来るようにzipして、テクスチャを送信するように構成します。
pmmp編
魔法のコードでスポーンできるようにします(minecraft:shulkerはオプションです。)
/** @var CompoundTag $nbt1 */
$nbt1 = StaticPacketCache::getInstance()->getAvailableActorIdentifiers()->identifiers->getRoot();
/** @var ListTag $tag */
$tag = $nbt1->getListTag("idlist");
$nbt = new CompoundTag();
$nbt->setString(self::KEY_BID, "minecraft:shulker");//happy_ghast
$nbt->setString(self::KEY_ID, "sod:yusilya");
$nbt->setByte(self::KEY_HAS_SPAW_EGG, (int) false);
$nbt->setByte(self::KEY_SUMMONABLE, (int) true);
$tag->push($nbt);
エンティティ登録
気合でバグを修正し、エンティティを登録します。
<?php
declare(strict_types=1);
namespace core\module\yuusilya;
use pocketmine\entity\EntitySizeInfo;
use pocketmine\entity\Living;
use pocketmine\event\entity\EntityDamageByEntityEvent;
use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\math\Vector3;
use pocketmine\nbt\tag\CompoundTag;
class YuusilyaEntity extends Living{
protected function getInitialSizeInfo() : EntitySizeInfo{
return new EntitySizeInfo(5, 5);
}
public static function getNetworkTypeId() : string{
return "sod:yusilya";
}
public function getName() : string{
return "yuusilya";
}
public function attack(EntityDamageEvent $source) : void{
if($source instanceof EntityDamageByEntityEvent){
$source->setKnockBack(0.0);
}
parent::attack($source);
}
protected function initEntity(CompoundTag $nbt) : void{
parent::initEntity($nbt);
$this->setScale(10);
}
}
EntityFactory::getInstance()->register(YuusilyaEntity::class, function(World $world, CompoundTag $nbt) : YuusilyaEntity{
return new YuusilyaEntity(Helper::parseLocation($nbt, $world), $nbt);
}, ['yuusilya']);
$ent = new YuusilyaEntity($player->getLocation()->asLocation(), null);
$ent->spawnToAll();
$ent->setMaxHealth(30);
$ent->setHealth(30);































