预设系统
预设系统是中国版提供的面向对象的游戏开发框架。通过将资源、实体和玩法逻辑组装成可复用的预设(Preset),你可以像搭积木一样构建游戏内容,大幅提高开发效率。
概述
预设就是"预先设定"——你将方块、素材、实体、特效和玩法逻辑拼装成一个整体,保存为 .preset 文件,存放在行为包的 Presets/ 目录中。
当预设被放置到游戏世界中时,就产生了一个实例(Instance)。同一个预设可以创建多个实例,每个实例独立运行。
预设文件 (.preset)
│
├─ 实例 A(世界坐标 100, 64, 200)
├─ 实例 B(世界坐标 -50, 70, 80)
└─ 实例 C(世界坐标 0, 65, 0)为什么需要预设
以塔防游戏为例,你需要复用的资源和逻辑有:
- 实体预设:各种怪物(带不同属性和 AI)
- 刷怪点零件:指定时间、地点、怪物组合的刷新逻辑
- 巡逻零件:怪物沿固定路径进攻的逻辑
搭建关卡时,只需将这些预设和零件组装好,就能快速制造出大量刷怪点和具有进攻逻辑的怪物。无需重复编写代码。
预设是通用概念
预设是各类游戏引擎(Unity Prefab、Unreal Blueprint)普遍使用的概念,核心目标是将游戏元素的资源和逻辑封装为可复用单元。
预设类型
中国版支持 6 种预设类型,覆盖不同的游戏对象:
| 类型 | 说明 | 必须绑定配置 |
|---|---|---|
| 实体预设 | 绑定实体配置,可添加模型、动画、特效、零件 | 是 |
| 玩家预设 | 定义玩家相关的逻辑和表现 | 否 |
| 方块预设 | 绑定方块配置,可添加零件实现方块交互逻辑 | 是 |
| 特效预设 | 粒子特效、序列帧动画等视觉效果 | 否 |
| 界面预设 | 界面(UI)相关的预设 | 否 |
| 文字面板预设 | 世界中的 3D 文字显示 | 否 |
配置绑定
实体预设和方块预设必须绑定一个配置才能使用。配置定义数据(JSON),预设定义表现和逻辑。两者是分离的。
零件系统
零件(Part) 是预设架构下的玩法逻辑模块。把逻辑写到零件中,再将零件挂接到预设下,逻辑就会随预设实例生效。
零件的核心优势
| 特性 | 说明 |
|---|---|
| 可复用 | 同一零件可挂接到不同预设 |
| 可配置 | 通过属性面板调整参数,无需修改代码 |
| 可继承 | 支持零件继承,扩展已有逻辑 |
| 分端运行 | 零件分为服务端零件和客户端零件 |
零件的工作方式
实体预设: 僵尸
├─ 素材: 僵尸模型 + 贴图
├─ 零件: 巡逻逻辑(服务端)
├─ 零件: 攻击逻辑(服务端)
└─ 零件: 受伤特效(客户端)同一个"巡逻逻辑"零件可以同时挂接到僵尸、骷髅、苦力怕的预设上,只需在属性面板中调整巡逻速度和路径参数。
预设编辑器
在 MC Studio 中通过顶部页签切换或双击 .preset 文件打开预设编辑器。
界面构成
| 面板 | 用途 |
|---|---|
| 层级面板 | 显示预设的父子结构树形图,管理素材、零件、子预设 |
| 预览窗 | 预设的 3D 预览,可拖拽调整坐标变换 |
| 属性面板 | 查看和修改选中条目的属性(预设属性、零件属性等) |
| 资源管理器 | 管理作品中的所有文件和目录 |
常用操作
添加内容(在层级面板根节点右键):
- 添加素材:给预设添加模型、贴图等素材
- 添加零件:给预设挂接逻辑零件
- 添加预设:给预设添加子预设
条目操作(在非根节点右键):
- 复制 / 粘贴 / 创建副本
- 重命名 / 删除
- 在资源管理器中定位
工具栏:
- 撤销 / 重做(支持无限次撤销)
- 保存 / 备份 / 运行
- 创建预设 / 创建零件
预设编辑是单文件操作
预设编辑器一次只能编辑一个预设。如果需要切换,在资源管理器中双击另一个 .preset 文件即可。
内置零件
中国版提供了一系列内置零件,覆盖常见玩法需求:
| 零件 | 说明 |
|---|---|
| 触发器 | 实体进入/离开指定区域时触发逻辑 |
| 玩家基础属性 | 管理玩家生命值、移速等基础属性 |
| 世界属性 | 管理世界级别的全局属性 |
| 相机轨迹 | 定义摄像机运动路径,用于过场动画 |
| 实体零件 | 实体的基本属性和行为 |
| 导航路径 | 定义 NPC / 怪物的移动路线 |
| 后处理 | 画面后处理效果(模糊、调色等) |
| 天空盒 | 自定义天空渲染效果 |
这些内置零件开箱即用。将它们挂接到预设上,在属性面板中配置参数即可生效。
自定义零件
内置零件不能满足需求时,你可以用 Python 开发自定义零件。
创建零件
在 MC Studio 中通过 新建文件向导 创建零件,选择服务端或客户端类型。零件代码保存在行为包的 Parts/ 目录中。
零件生命周期
class MyCustomPart(object):
def __init__(self):
# 零件创建时调用
pass
def InitClient(self):
# 客户端初始化(仅客户端零件)
pass
def InitServer(self):
# 服务端初始化(仅服务端零件)
pass
def TickServer(self):
# 服务端每帧调用
pass
def DestroyServer(self):
# 服务端销毁时调用
pass生命周期顺序:Create → Init → Tick(每帧) → Destroy
零件通讯
零件之间通过消息机制进行通讯。同一预设实例下的零件可以直接发送消息,跨预设则通过事件广播。
与脚本的关系
预设系统底层编译为 Python 代码。你可以在 Python 脚本中通过 PresetAPI 操作预设:
import mod.server.extraServerApi as serverApi
# 获取 PresetAPI
presetApi = serverApi.GetPresetApi()
# 创建预设实例
pos = (100, 64, 200)
rot = (0, 0, 0)
instance = presetApi.CreatePreset("my_namespace:my_preset", pos, rot)
# 销毁预设实例
presetApi.DestroyPreset(instanceId)预设、零件、蓝图三者的关系:
| 层级 | 说明 |
|---|---|
| 预设 | 容器,组装资源和零件 |
| 零件 | 逻辑模块,可用 Python 或蓝图编写 |
| 蓝图 | 可视化编程方式编写零件逻辑 |
推荐路径
新手建议从蓝图零件入手,熟悉预设架构后再过渡到 Python 自定义零件。详细 API 参见 PresetAPI 参考。
