v3.0.0 新增
自定义设置页用 React 替换扩展设置的自动表单。适合自动表单摆不下的情况:想加实时预览、让几个设置联动,或者按自己的分组排列。 设置的类型和默认值仍以 static settings 为准,设置页只决定这些设置怎么摆、怎么改。 写设置页前,先读 Studio 组件包里的「两个入口」和「构建」。

显示在哪里

设置页在 Studio 里替换自动表单的位置有两处:
  • 个性化 → 项目设置:在左侧扩展树选中扩展后的设置区;
  • 剧本工具栏最右端的「扩展」菜单:选择一个扩展后打开的「扩展设置」对话框。
设置清单一个字段都没有时,不会显示设置页。

开始制作

1

声明设置

在运行时入口用 static settings 声明设置。
2

准备编辑期入口

新扩展在初始化程序前打开「同时生成自定义设置页模板」;已有扩展按 Studio 组件包的「已有扩展」步骤添加。
3

导出设置页

在 src/studio.tsx 写好组件,以 settingsPage 这个名字导出。
4

构建

运行 npm run build 生成两个入口。开发时用 npm run watch,保存后 Studio 自动刷新。
下面是模板生成的例子。运行时入口声明两个设置:
// src/index.tsx
@extension({ id: "welcome", label: "欢迎画面" })
export class WelcomeExtension extends Extension<WelcomeUIProps> {
  static settings = settings((s) => ({
    title: s.string("标题").default("我的游戏").describe("显示在欢迎画面的大标题里。"),
    accentColor: s.color("强调色").default("#E5675A"),
  }));
  // ……
}
编辑期入口决定怎么编辑它们:
// src/studio.tsx
import {
  ColorPicker,
  FieldRow,
  Panel,
  Section,
  SettingField,
  useSetting,
} from "@avg-studio/studio-ui";

/** 强调色这一行:自己读写设置,改颜色时只重新渲染这一行。 */
function AccentColorRow() {
  const [accentColor, setAccentColor] = useSetting<string>("welcome.accentColor");
  return (
    <FieldRow label="强调色" description="欢迎画面标题里部分文字的颜色。">
      <ColorPicker value={accentColor} onChange={setAccentColor} ariaLabel="强调色" />
    </FieldRow>
  );
}

function WelcomeSettingsPage() {
  return (
    <Panel>
      <Section title="欢迎画面" description="改动会立即保存,预览里的欢迎画面同步更新。">
        <SettingField name="welcome.title" divider />
        <AccentColorRow />
      </Section>
    </Panel>
  );
}

export const settingsPage = WelcomeSettingsPage;

设置名

useSetting、SettingField、AutoSettings 和 ShortcutInput 的 name 都是同一个设置名:
设置写在哪里设置名例子
Extension 类的 static settings,不论这个类有没有界面模块 id.字段名welcome.title
入口模块直接导出的共享清单 export const settingsSchema字段名debugLog
模块 id 依次取类上的 static uiId、@extension({ id });都没写时取类名的短横线写法,TitleScreen 对应 title-screen。 名字写错不会抛错:读到空值,写入被拒,扩展日志会提示。SettingField 还会在原位显示红字「设置清单里没有…」。

读写设置

useSetting(name)

const [title, setTitle, info] = useSetting<string>("welcome.title");
返回值说明
title当前生效的值,没改过时是设置清单的默认值
setTitle(next)检查后写入,通过返回 true,被拒返回 false;不传值表示恢复默认值
info.isModified是否已修改
info.isEnabled字段的 enabledWhen 是否满足。不满足时怎么表现由页面决定
info.defaultValue设置清单声明的默认值
info.reset()恢复默认值
写入成功后自动保存,预览立即生效。

写入前的值检查

setValue 写入前按设置清单检查,不符合就拒绝,原因写进扩展日志:
字段类型写入的值必须是
字符串、素材、界面引用、角色字符串
数字有限的数字,并在 .range() 范围内
布尔true 或 false
枚举声明过的选项
颜色合法的颜色写法
快捷键规范写法,如 Ctrl+KeyH、F5;空字符串表示未绑定
列表数组,每行是对象,逐格按上面的规则检查,行数不超过 maxItems
写入列表时,每行里清单没有声明的列会先被去掉。
function OffsetRow() {
  const [offset, setOffset, { isModified, reset }] = useSetting<number>("welcome.offset");
  return (
    <FieldRow label="边缘距离">
      <Row>
        <NumberSlider value={offset} onChange={setOffset} min={8} max={160} unit="px" />
        {isModified && <Button variant="ghost" onClick={reset}>恢复默认</Button>}
      </Row>
    </FieldRow>
  );
}

混用现成字段

不需要每一行都自己写:
  • SettingField:一行现成字段,和自动表单一样带标签、说明、已修改圆点、重置按钮和 enabledWhen 置灰。divider 可以在下方画分隔线。
  • AutoSettings:整段自动表单,带分组、搜索和「只看已修改」。include、exclude 用来挑选设置。
把 AutoSettings 直接放在 Panel 里,不要放进 Section,否则搜索栏滚动时不能停在顶部。
function SettingsPage() {
  return (
    <Panel>
      <Section title="外观">
        <SettingField name="welcome.title" divider />
        <AccentColorRow />
      </Section>
      <AutoSettings exclude={["welcome.title", "welcome.accentColor"]} />
    </Panel>
  );
}

编辑工程数据库集合

设置页可以用 useDataCollection(alias) 直接维护本扩展绑定的数据集合,比如在设置页里管理道具目录。它和数据表页共用同一份原始资料。
function ItemTools() {
  const items = useDataCollection("items");
  async function addItem() {
    try {
      await items.insertOne({ name: "药水", price: 20 });
    } catch (error) {
      toast({ title: "新增失败", description: String(error), type: "error" });
    }
  }
  return <Button disabled={items.revision === null} onClick={() => void addItem()}>新增道具</Button>;
}
完整接口、草稿与版本冲突的处理见项目数据库 API。

读取剧本和场景

需要从剧本里收集内容时,用 useStorySnapshot() 读取只读快照。需要预览图片时,用 ImagePreview。需要知道鉴赏界面的来源时,用 useGallerySources()。说明见 Studio 组件包。

出错与刷新

情况Studio 怎么处理
还没有构建提示「自定义设置页还没有构建,先显示自动表单;构建完成后会自动切换。」,下面是自动表单
加载失败显示「自定义设置页加载失败」和原因,提供「重试」和「改用自动表单」
渲染时抛错显示「自定义设置页出错了」,提供「重试」和「改用自动表单」。错误和组件栈写进扩展日志
选了「改用自动表单」显示「重新加载自定义设置页」按钮,切换扩展或重新构建后回到设置页
重新构建设置页自动刷新,之前出错的修好后也会恢复
加载失败的具体原因和改法见 Studio 组件包。