開始之前!
FreeMinecraftModels (FMM) 目前正在積極開發中!這意味著某些功能尚未完成,正在積極開發中。
然而,目前插件的核心功能已完全可用 - 轉換 bbmodel 檔案、生成資源包、在遊戲中生成實體並管理其動畫、放置持久性道具的能力,這些都已基本完成。
請考慮在 https://www.patreon.com/magmaguy 支持開發!
匯出的資源包內容在 FreeMinecraftModels 這邊採用 CC0 授權,不保留任何權利。您可以自由使用、分發、修改,用於任何目的,無需任何限制或署名。
使用此插件
FreeMinecraftModels (FMM) 能為 Minecraft 伺服器管理員做什麼?
它可以:
- 匯入 .bbmodel 或 fmmodel(FFM 的自訂格式)模型
- 生成超過正常 Minecraft 資源包模型限制的資源包(最高 112x112x112 單位或遊戲內 7x7x7 方塊,使用多個骨骼時實際上無限制)
- 在遊戲中顯示這些模型,向基岩版客戶端發送特定的基岩版相容數據包,同時向 1.19.4+ Java 版客戶端發送顯示實體
- 按照在 Blockbench 中配置的方式為這些模型製作動畫
- 處理默認狀態動畫,無需其他插件(行走、待機、死亡、攻擊、生成)
- 處理隨底層實體旋轉且具有不同 x 和 z 軸的碰撞箱
- 管理三種類型的模型:靜態、動態和道具
- 道具是持久性的,可以放置在世界中,即使伺服器重啟也會保留,並且可以將帶有道具的地圖分發到其他伺服器
- 動態模型適用於需要底層生物實體才能運作的模型,理想情況下由自訂首領插件或寵物插件使用
- 靜態模型適用於不應該移動的非持久性模型,基本上是臨時裝飾或效果
如何添加現有模型?
要匯入模型,只需將 .bbmodel 拖到 imports 資料夾中並執行 /fmm reload。這將在 models 資料夾中生成一個 .fmmodel 檔案,並將模型添加到 outputs 資料夾中的資源包。
您需要使用該資源包才能正確查看模型! 這是一個普通的資源包,所以您只需要將其放入您的資源包資料夾中。Minecraft 伺服器有一種託管資源包的方式。我推薦使用我的插件 ResourcePackManager,它會自動抓取檔案並遠端託管它們,甚至將它們與其他插件的檔案合併。
如何在遊戲中查看模型?
需要注意的是,雖然 FreeMinecraftModels 可以作為獨立插件用於查看道具(基本上是您可以放置在世界中的自訂模型),但該插件通常在與諸如 EliteMobs 等插件配對時效果最佳,在這種情況下,模型會被積極用於具體的事情,例如首領戰鬥。
有三種類型的模型:靜態、動態和道具。
- 道具是持久性的,可以放置在世界中,即使伺服器重啟也會保留,並且可以將帶有道具的地圖分發到其他伺服器
- 動態模型適用於需要底層生物實體才能運作的模型,理想情況下由自訂首領插件或寵物插件使用
- 靜態模型適用於不應該移動的非持久性模型,基本上是臨時裝飾或效果
在遊戲中查看靜態模型
要在遊戲中查看靜態模型,請使用命令 /fmm spawn static <id>,其中 id 是模型的檔案名稱,使用小寫且不帶副檔名。
在遊戲中查看動態模型
要在遊戲中查看動態模型,請使用命令 /fmm spawn dynamic <id>,其中 id 是模型的檔案名稱,使用小寫且不帶副檔名。
在遊戲中查看道具
要在遊戲中查看動態模型,請使用命令 /fmm spawn prop <id>,其中 id 是模型的檔案名稱,使用小寫且不帶副檔名。
FreeMinecraftModels (FMM) 能為建模師做什麼?
FMM 遵循資源包生成的標準資源包規則。此外,它盡可能與 ModelEngine 相容的模型保持相容,以嘗試標準化跨插件的模型創建。
模型生成功能/限制
如果您曾經為 ModelEngine 創建過模型,您將熟悉許多 Minecraft 資源包生成限制:
方塊:
這裡的方塊與 Blockbench 中的方塊相同,它們是組成模型的立方體。
- 方塊最高可達 112x112x112「像素」(Blockbench 單位)或遊戲內 7x7x7 方塊(使用顯示大小繞過正常的 Minecraft 限制,很快將通過顯示實體進一步繞過 1.19.4+)
- 方塊的合法旋轉為 0、22.5、-22.5、45 和 -45。其他旋轉不起作用。
- 方塊只在一個軸上旋轉,這意味著 [22.5, 0, 0] 的旋轉是可以的,[22.5, 0, 45] 的旋轉將無法完全工作,只會在一個軸上旋轉。
骨骼:
骨骼是 Blockbench 所說的「群組」。它們用於將方塊分組在一起,應該用於將骨骼分組在一起以進行動畫。
- 骨骼最高可達 112x112x112「像素」(Blockbench 單位)或遊戲內 7x7x7 方塊。請注意,骨骼的大小由其包含的內容設定,所以如果您的方塊相距超過 7 個方塊,您可能會超過此大小限制。繞過此限制的方法很簡單,只需將方塊放在不包含在第一個骨骼中的不同骨骼中!
- 可以有任何旋轉!但是,建議避免使用 90、-90、180 和 -180 的默認旋轉,因為這些通常會導致意外行為。請注意,這並不真正適用於動畫,只是骨骼的默認靜止位置。
骨骼比方塊靈活得多,但您應該使用盡可能少的骨骼!在 FMM 中,由於 Minecraft 的限制,每個骨骼都是一個不同的實體。在規模上,這將很快影響性能!始終使用盡可能少的骨骼,並注意您計劃生成該模型的數量 - 您計劃擁有的越多,您應該擁有的骨骼就越少!
虛擬骨骼
虛擬骨骼是模型引擎術語,用於具有特定元數據的骨骼,通常採用特定名稱的形式,用於特定目的。
以下虛擬骨骼已在 FreeMinecraftModels 中實現:
- 碰撞箱/眼睛高度:一個名為「hitbox」的骨骼,帶有定義邊界的立方體,並且具有相同的 x 和 z 值(如果它們不相同,將選擇最大值)定義碰撞箱。眼睛高度設定在碰撞箱骨骼的樞軸點。
- 名稱標籤:名稱以「tag_」開頭的骨骼。老實說,我更喜歡在這裡更具體一些,使用「tag_name」以便將標籤用於其他事情,但這將在稍後認真考慮。
- 頭部:名稱以 h_ 開頭的骨骼。這是一個虛擬骨骼,用於定義模型的頭部,它將根據底層實體的頭部旋轉而旋轉。
更安全、更容易、不可編輯的檔案分發
FMM 嘗試解決的一件事是,用戶將他們獲得的模型重新用於以模型創建者不希望他們編輯的方式編輯它們,特別是為了重新換膚或以其他方式稍微改變模型,並可能嘗試作為原創作品轉售。
為此,FMM 使用 .fmmodel 檔案格式,旨在將 .bbmodel 檔案簡化到可以由插件使用但無法在 Blockbench 中編輯的程度。
作為建模師,您現在可以選擇是否要發布不可編輯的 .fmmodel 檔案、可編輯的 .bbmodel 檔案,甚至為兩者制定差異化定價或分發服務條款。
生成 .fmmodel 很簡單,只需將您的 .bbmodel 放入 ~/plugins/FreeMinecraftModels/imports 資料夾,然後使用 /fmm reload 重新載入插件或重啟伺服器。您的 .fmmodel 將位於 ~/plugins/FreeMinecraftModels/models 資料夾中。
FreeMinecraftModels (FMM) 能為想要將其整合到插件中的開發者做什麼?
FMM 有一個 maven 存儲庫! Maven:
<repository>
<id>magmaguy-repo-releases</id>
<name>MagmaGuy's Repository</name>
<url>https://repo.magmaguy.com/releases</url>
</repository>
<dependency>
<groupId>com.magmaguy</groupId>
<artifactId>FreeMinecraftModels</artifactId>
<version>LATEST.VERSION.HERE</version>
</dependency>
Gradle:
maven {
name = "magmaguyRepoReleases"
url = uri("https://repo.magmaguy.com/releases")
}
compileOnly group : 'com.magmaguy', name: 'FreeMinecraftModels', version: 'LATEST.VERSION.HERE'
注意 FreeMinecraftModels 旨在用作 API,並且需要在伺服器上安裝插件。不要將其打包到您的插件中!
API 使用
FMM 旨在盡可能易於作為 API 使用。
現在,如果您希望使用 FreeMinecraftModels 作為 API 來使用自訂模型,您只需要了解四個類:
ModeledEntity- 所有實體的基礎類StaticEntity- 當您想要使用非永久靜態模型時DynamicEntity- 當您想要用模型偽裝另一個生物實體時PropEntity- 當您想要在世界中放置即使伺服器重啟也會保留的模型時
以下是處理靜態模型的程式碼片段:
import org.bukkit.Bukkit;
public class FreeMinecraftModelsModel {
private StaticEntity staticEntity = null;
//Create the model
public FreeMinecraftModelsModel(String id, Location location) {
//This spawns the entity!
staticEntity = StaticEntity.create(id, location);
//This checks if the entity spawned correctly
if (staticEntity == null) Bukkit.getLogger().warning(("FMM failed to find a model named " + id + " !"));
}
public void remove() {
//This removes the entity
staticEntity.remove();
}
}
請記住,靜態模型旨在停留在原地並充當固定位置的裝飾元素(動畫在這裡不算作「移動」)。雖然可以移動它們,但如果這是您的目的,請考慮您是否可能想要使用動態模型。
以下是我的自訂首領插件 EliteMobs 如何使用動態實體:
package com.magmaguy.elitemobs.thirdparty.custommodels.freeminecraftmodels;
import com.magmaguy.elitemobs.thirdparty.custommodels.CustomModelInterface;
import api.com.magmaguy.freeminecraftmodels.ModeledEntityManager;
import customentity.com.magmaguy.freeminecraftmodels.DynamicEntity;
import lombok.Getter;
import org.bukkit.entity.LivingEntity;
public class CustomModelFMM implements CustomModelInterface {
@Getter
private DynamicEntity dynamicEntity;
public CustomModelFMM(LivingEntity livingEntity, String modelName, String nametagName) {
dynamicEntity = DynamicEntity.create(modelName, livingEntity);
if (dynamicEntity == null) return;
dynamicEntity.setName(nametagName);
}
public static void reloadModels() {
ModeledEntityManager.reload();
}
public static boolean modelExists(String modelName) {
return ModeledEntityManager.modelExists(modelName);
}
@Override
public void shoot() {
if (dynamicEntity.hasAnimation("attack_ranged")) dynamicEntity.playAnimation("attack_ranged", false);
else dynamicEntity.playAnimation("attack", false);
}
@Override
public void melee() {
if (dynamicEntity.hasAnimation("attack_melee")) dynamicEntity.playAnimation("attack_melee", false);
else dynamicEntity.playAnimation("attack", false);
}
@Override
public void playAnimationByName(String animationName) {
dynamicEntity.playAnimation(animationName, false);
}
@Override
public void setName(String nametagName, boolean visible) {
dynamicEntity.setName(nametagName);
dynamicEntity.setNameVisible(visible);
}
@Override
public void setNameVisible(boolean visible) {
dynamicEntity.setNameVisible(visible);
}
@Override
public void switchPhase() {
dynamicEntity.stopCurrentAnimations();
}
}
動態模型建立在生物實體之上,可以在使用上述範例中的 create 方法時提供,也可以在動態實體上執行 spawn 方法時提供。
作為開發者為 FreeMinecraftModels (FMM) 專案做出貢獻
FMM 在 GPLV3 授權下分發,歡迎程式碼貢獻。以下是基本的貢獻指南:
- 遵循現有的命名約定,保持現有的詳細程度,並添加足夠的文檔,使您的貢獻易於理解
- 保持貢獻與插件的範圍相關。如果您不知道它是否相關,請隨時提前詢問。
- 注意您的程式碼的性能影響。如果貢獻過於未優化或導致性能影響過大,某些貢獻可能會被拒絕。
一般插件概述
為了節省您的時間,這裡快速分解一下 FMM 的邏輯流程:
- 讀取
imports資料夾 - 將檔案從
imports資料夾移動到models資料夾。如果檔案是.bbmodel,它會在models資料夾中轉換為.fmmodel。 - 讀取
models資料夾中的檔案。 - 解釋所有模型結構,創建包含
Bone群組的Skeleton,這些骨骼包含子Bone和Cube的群組。Cube和Bone生成它們各自相關的 JSON 資源包數據。這意味著Cube生成特定於方塊的 JSON,Bone生成大綱和單個骨骼檔案。請注意,一個骨骼會產生一個資源包檔案。模型在生成時會添加到列表中。 - 仍然在
Skeleton中,解釋模型中的所有Animations(如果有) - 所有數據現在都已初始化,資源包已在
outputs資料夾中生成,插件已準備好使用。
此插件中使用的技巧:
這裡使用的技巧已經相當成熟和標準化,但仍會列出,因為它們可能違反直覺。
請注意,這些技巧對用戶和模型製作者完全不可見;列出的限制和解決方法僅為了幫助您理解 FMM 如何繞過各種 Minecraft 限制。
- 所有模型都放大 4 倍,然後在程式碼中重新調整大小和樞軸點,以擴展模型的理論最大大小
- 因為資源包模型只能具有從 -16 到 +32 的大小,所以模型會在後台移動。這對玩家完全不可見。
- 皮革馬鎧用於創建可以通過程式碼影響色調的模型(即用於傷害指示)。馬鎧必須設定為白色才能顯示正確的顏色!
- Blockbench 對紋理使用特定的 ID 系統,但實際上從配置中按順序讀取紋理。這裡根據它們在紋理列表中的位置分配 ID,遵循 Blockbench 的做法。
- 由於 Minecraft 的限制,每個骨骼都是一個不同的實體
- 皮革馬鎧在盔甲架的頭部槽位
- 盔甲架和顯示實體都用於默認靜態物品;基岩版客戶端獲得盔甲架,1.19.4+ 客戶端獲得顯示實體(較舊的客戶端將獲得盔甲架)
為 FreeMinecraftModels (FMM) 專案做出一般貢獻
FMM 實際上是由 https://www.patreon.com/magmaguy 上的可愛人們眾籌的!所有貢獻的幫助都超出您的想像 ;)
目前計劃的功能:
- 基岩版客戶端 RSP 生成
- RSP 管理與 geyser 整合
- tag_projectile 作為元骨骼,可以從中發射彈丸(每個模型可以有多個)
目前希望修復的奇怪限制:
- TransformationMatrix 很混亂,但尚未開發出更好的解決方案。它們需要一些擅長矩陣的人來做一些工作。