自定义基础生物
自定义生物是附加包开发中最复杂也最有成就感的部分。你需要同时配置行为包(服务端逻辑)和资源包(客户端渲染),涉及模型、动画、材质、渲染控制器等多个子系统。
前置条件
建议先了解基础概念和附加包开发。推荐使用 Blockbench 制作模型与动画。
概述
创建一个完整的自定义生物,通常需要以下文件:
| 文件 | 位置 | format_version | 说明 |
|---|---|---|---|
| 行为包实体 | BP/entities/ | 1.10.0 | 服务端逻辑:组件、AI、生命值 |
| 客户端实体 | RP/entity/ | 1.10.0 | 材质/贴图/模型/动画的绑定 |
| 模型 | RP/models/entity/ | 1.12.0 | 几何体:骨骼、方块体 |
| 动画 | RP/animations/ | 1.8.0 | 关键帧动画:待机、行走 |
| 动画控制器 | RP/animation_controllers/ | 1.10.0 | 状态机:切换动画 |
| 渲染控制器 | RP/render_controllers/ | 1.10.0 | 控制材质/贴图/模型的选择 |
| 贴图 | RP/textures/entity/ | — | PNG 贴图文件 |
| 材质 | RP/materials/ | — | 着色器配置(可选) |
| 本地化 | RP/texts/zh_CN.lang | — | 显示名称 |
中国版路径说明
行为包实体放在 entities/ 目录(与国际版一致),但中国版有额外的 netease: 组件和 Python Mod SDK 可用于扩展实体行为。
行为包实体定义
行为包实体 JSON 放在 BP/entities/ 目录下,定义了生物的服务端逻辑。
{
"format_version": "1.10.0",
"minecraft:entity": {
"description": {
"identifier": "mymod:ghost",
"is_spawnable": true,
"is_summonable": true,
"is_experimental": false
},
"component_groups": {
"mymod:baby": {
"minecraft:scale": { "value": 0.5 },
"minecraft:is_baby": {}
},
"mymod:adult": {
"minecraft:scale": { "value": 1.0 },
"minecraft:loot": {
"table": "loot_tables/entities/ghost.json"
}
}
},
"components": {
"minecraft:type_family": {
"family": ["ghost", "monster", "mob"]
},
"minecraft:physics": {},
"minecraft:collision_box": {
"width": 0.8,
"height": 1.8
},
"minecraft:health": {
"value": 20,
"max": 20
},
"minecraft:movement": {
"value": 0.25
},
"minecraft:movement.basic": {},
"minecraft:navigation.walk": {
"can_walk": true,
"avoid_water": true,
"avoid_damage_blocks": true
},
"minecraft:follow_range": {
"value": 16,
"max": 32
},
"minecraft:attack": {
"damage": 4
},
"minecraft:behavior.melee_attack": {
"priority": 2,
"speed_multiplier": 1.2,
"track_target": true
},
"minecraft:behavior.nearest_attackable_target": {
"priority": 1,
"within_radius": 16,
"entity_types": [
{
"filters": {
"test": "is_family",
"subject": "other",
"value": "player"
},
"max_dist": 16
}
]
},
"minecraft:behavior.hurt_by_target": {
"priority": 0
},
"minecraft:behavior.random_stroll": {
"priority": 5,
"speed_multiplier": 0.8
},
"minecraft:behavior.look_at_player": {
"priority": 6,
"look_distance": 8
},
"minecraft:pushable": {
"is_pushable": true,
"is_pushable_by_piston": true
},
"minecraft:experience_reward": {
"on_death": "query.last_hit_by_player ? 5 : 0"
},
"minecraft:despawn": {
"despawn_from_distance": {
"max_distance": 128,
"min_distance": 32
}
}
},
"events": {
"minecraft:entity_spawned": {
"randomize": [
{ "weight": 80, "add": { "component_groups": ["mymod:adult"] } },
{ "weight": 20, "add": { "component_groups": ["mymod:baby"] } }
]
}
}
}
}description 字段
| 字段 | 类型 | 说明 |
|---|---|---|
identifier | string | 唯一标识符,格式 namespace:name |
is_spawnable | bool | 是否可通过刷怪蛋生成 |
is_summonable | bool | 是否可通过 /summon 命令召唤 |
is_experimental | bool | 是否需要开启实验性玩法 |
常用行为组件速查
| 组件 | 说明 |
|---|---|
minecraft:physics | 启用物理(重力、碰撞) |
minecraft:collision_box | 碰撞箱尺寸 (width, height) |
minecraft:health | 生命值 (value, max) |
minecraft:movement | 移动速度 (value) |
minecraft:movement.basic | 基础移动模式 |
minecraft:navigation.walk | 地面寻路 (can_walk, avoid_water, can_open_doors) |
minecraft:follow_range | 跟随/追踪范围 |
minecraft:attack | 攻击伤害 (damage) |
minecraft:behavior.melee_attack | 近战攻击 AI |
minecraft:behavior.nearest_attackable_target | 寻找最近目标 AI |
minecraft:behavior.hurt_by_target | 被攻击后还击 AI |
minecraft:behavior.random_stroll | 随机漫步 AI |
minecraft:behavior.look_at_player | 看向玩家 AI |
minecraft:type_family | 类型族(用于过滤) |
minecraft:loot | 掉落表 |
minecraft:experience_reward | 经验掉落 |
minecraft:pushable | 可推动性 |
minecraft:knockback_resistance | 击退抗性 (value: 0.0-1.0) |
minecraft:scale | 缩放 (value) |
minecraft:despawn | 自动消失距离 |
component_groups 与 events
component_groups 是预定义的组件集合,通过 events 动态添加或移除。
事件触发方式
| 事件 | 触发时机 |
|---|---|
minecraft:entity_spawned | 实体首次生成时 |
minecraft:entity_born | 实体被繁殖生成时 |
minecraft:entity_transformed | 实体被转化时 |
| 自定义事件 | 通过组件触发(如 minecraft:environment_sensor) |
randomize 与 sequence
"events": {
"minecraft:entity_spawned": {
"sequence": [
{ "add": { "component_groups": ["mymod:base"] } },
{
"randomize": [
{ "weight": 50, "add": { "component_groups": ["mymod:variant_a"] } },
{ "weight": 50, "add": { "component_groups": ["mymod:variant_b"] } }
]
}
]
}
}randomize:按权重随机选择一个分支执行sequence:按顺序依次执行每个分支
过滤器 (Filters)
事件可通过 filters 条件控制是否执行:
{
"filters": {
"test": "is_daytime",
"value": true
},
"add": { "component_groups": ["mymod:daytime_variant"] }
}常用过滤器:is_family、is_daytime、has_component、is_underwater、in_water、on_ground。
资源包客户端实体定义
客户端实体 JSON 放在 RP/entity/ 目录下,将模型、贴图、动画等资源绑定到实体。
{
"format_version": "1.10.0",
"minecraft:client_entity": {
"description": {
"identifier": "mymod:ghost",
"materials": {
"default": "entity_alphatest"
},
"textures": {
"default": "textures/entity/ghost"
},
"geometry": {
"default": "geometry.ghost"
},
"animations": {
"idle": "animation.ghost.idle",
"walk": "animation.ghost.walk",
"controller": "controller.animation.ghost"
},
"scripts": {
"animate": ["controller"]
},
"render_controllers": [
"controller.render.ghost"
],
"spawn_egg": {
"texture": "ghost_spawn_egg",
"texture_index": 0
},
"enable_attachables": true
}
}
}关键字段说明
| 字段 | 说明 |
|---|---|
materials | 材质短名 → 材质名映射 |
textures | 贴图短名 → 贴图路径映射(不含扩展名) |
geometry | 模型短名 → geometry 标识符映射 |
animations | 动画短名 → 动画/控制器标识符映射 |
scripts.animate | 根动画列表,支持条件播放 |
render_controllers | 渲染控制器列表 |
spawn_egg | 刷怪蛋贴图配置 |
enable_attachables | 允许手持物品显示 |
自定义模型
使用 Blockbench 创建 Bedrock Entity 类型模型,导出为 .geo.json(format_version 1.12.0)。模型由骨骼(bones)和方块体(cubes)组成,支持定位器(locators)用于粒子/拴绳附着。
详细内容请参考 → 自定义模型
自定义动画
动画定义骨骼在各时间点的旋转、位置和缩放(format_version 1.8.0)。动画控制器是状态机,根据查询条件在不同动画之间切换(format_version 1.10.0)。
详细内容请参考 → 动画与动画控制器
渲染控制器与材质
渲染控制器决定使用哪个材质、贴图和模型来渲染实体。支持多变体(Arrays)、贴图分层、骨骼可见性控制等。材质通过继承链定义着色器行为。
详细内容请参考 → 渲染控制器与材质
脚本驱动 (query.mod.*)
中国版支持通过 Python 脚本注册自定义查询变量,可在动画和动画控制器中使用。
注册自定义 Query
# 客户端脚本
import mod.client.extraClientApi as clientApi
compFactory = clientApi.GetEngineCompFactory()
def on_client_init(self, event):
levelId = clientApi.GetLevelId()
queryComp = compFactory.CreateQueryVariable(levelId)
queryComp.Register('query.mod.is_attacking', 0.0)设置 Query 值
def on_attack_start(self, entityId):
queryComp = compFactory.CreateQueryVariable(entityId)
queryComp.Set('query.mod.is_attacking', 1.0)在动画控制器中使用
"transitions": [
{ "attack": "query.mod.is_attacking > 0" }
]命名规则
自定义 Query 变量必须以 query.mod. 开头。注册时使用 Register 方法定义默认值,然后通过 Set 方法在运行时修改。
自定义 AI (python_custom)
中国版支持用 Python 实现完全自定义的 AI 行为。
行为包组件注册
"components": {
"minecraft:behavior.python_custom:patrol": {
"priority": 3,
"control_flags": ["move", "look"]
}
}control_flags 可选值:move、look、jump。多个 AI 行为之间会根据 flag 互斥。
Python AI 类
# -*- coding: utf-8 -*-
import mod.server.extraServerApi as serverApi
ServerSystem = serverApi.GetServerSystemCls()
compFactory = serverApi.GetEngineCompFactory()
class PatrolGoal(serverApi.GetCustomGoalCls()):
"""自定义巡逻 AI"""
def __init__(self, entityId, argsJson):
super(PatrolGoal, self).__init__(entityId, argsJson)
self.entityId = entityId
self.patrolPoints = [
(100, 65, 100),
(110, 65, 100),
(110, 65, 110),
(100, 65, 110),
]
self.currentIndex = 0
def CanUse(self):
"""判断是否可以启用此 AI(每 tick 调用)"""
# 没有攻击目标时才巡逻
targetComp = compFactory.CreateAction(self.entityId)
return not targetComp.GetAttackTarget()
def CanContinueToUse(self):
"""判断是否可以继续执行(每 tick 调用)"""
return self.CanUse()
def Start(self):
"""AI 启动时调用"""
self._moveToNext()
def Stop(self):
"""AI 停止时调用"""
pass
def Tick(self):
"""每 tick 调用"""
posComp = compFactory.CreatePos(self.entityId)
pos = posComp.GetFootPos()
target = self.patrolPoints[self.currentIndex]
dx = pos[0] - target[0]
dz = pos[2] - target[2]
if dx * dx + dz * dz < 4.0:
self.currentIndex = (self.currentIndex + 1) % len(self.patrolPoints)
self._moveToNext()
def _moveToNext(self):
target = self.patrolPoints[self.currentIndex]
moveComp = compFactory.CreateMoveTo(self.entityId)
moveComp.SetMoveSetting(target, 1.0)注册 AI 类
在服务端系统中注册:
class MyServerSystem(ServerSystem):
def __init__(self, namespace, systemName):
ServerSystem.__init__(self, namespace, systemName)
serverApi.RegisterCustomGoal('patrol', PatrolGoal)AI 执行流程
每 tick:遍历所有已注册的 AI → 按 priority 排序 → 调用 CanUse() → 如果返回 True 且 control_flags 不冲突 → 调用 Start() → 之后每 tick 调用 Tick() 和 CanContinueToUse()。
本地化
在 RP/texts/zh_CN.lang 中添加:
entity.mymod:ghost.name=幽灵
item.spawn_egg.entity.mymod:ghost.name=幽灵刷怪蛋完整示例文件结构
behavior_pack/
├── entities/
│ └── ghost.json ← 行为包实体定义
├── loot_tables/entities/
│ └── ghost.json ← 掉落表
└── manifest.json
resource_pack/
├── entity/
│ └── ghost.entity.json ← 客户端实体定义
├── models/entity/
│ └── ghost.geo.json ← 模型
├── animations/
│ └── ghost.animation.json ← 动画
├── animation_controllers/
│ └── ghost.ac.json ← 动画控制器
├── render_controllers/
│ └── ghost.rc.json ← 渲染控制器
├── textures/entity/
│ └── ghost.png ← 贴图
├── texts/
│ └── zh_CN.lang ← 本地化
└── manifest.json常见问题
实体不可见
- 检查客户端实体的
identifier是否与行为包一致 - 检查贴图路径是否正确(不含
.png扩展名) - 检查 geometry 标识符是否匹配
实体没有 AI / 不动
- 确认添加了
minecraft:physics和minecraft:movement.basic - 确认有
minecraft:navigation.walk - 检查
behavior.*组件的priority值(数值越小优先级越高)
模型位置偏移
- 检查模型骨骼的
pivot是否正确 - 确保模型在 Blockbench 中居中于原点
动画不播放
- 确认动画在客户端实体
animations中注册 - 确认在
scripts.animate中引用了动画控制器 - 检查动画控制器的
transitions条件是否正确
刷怪蛋不显示
- 确认
is_spawnable为 true - 确认
spawn_egg配置了正确的贴图
