> For the complete documentation index, see [llms.txt](https://docs.convai.com/api-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/ui-and-presentation/settings-panel/runtime-settings-api.md).

# 运行时设置 API

`IConvaiRuntimeSettingsService` 是内置设置面板下方的脚本层。任何脚本都可以读取当前设置快照、以原子方式应用补丁、订阅变更事件，并控制公开哪些转录模式——即使场景中没有该面板。

通过以下方式访问该服务 `ConvaiManager`:

```csharp
ConvaiManager.ActiveManager.TryGetRuntimeSettingsService(out var settings);
```

### `IConvaiRuntimeSettingsService`

| 成员                                                                             | 类型                                           | 说明                                  |
| ------------------------------------------------------------------------------ | -------------------------------------------- | ----------------------------------- |
| `当前`                                                                           | `ConvaiRuntimeSettingsSnapshot`              | 所有当前设置值的不可变快照                       |
| `SupportedTranscriptModes`                                                     | `IReadOnlyCollection<ConvaiTranscriptMode>`  | 当前注册为可供选择的转录模式                      |
| `已更改`                                                                          | `event Action<ConvaiRuntimeSettingsChanged>` | 每当任意设置发生变化时触发                       |
| `Apply(ConvaiRuntimeSettingsPatch patch)`                                      | `ConvaiRuntimeSettingsApplyResult`           | 以原子方式应用一个或多个设置。补丁中留空的字段 `null` 保持不变 |
| `ResetToDefaults()`                                                            | `ConvaiRuntimeSettingsApplyResult`           | 将所有设置重置为项目默认值                       |
| `SetSupportedTranscriptModes(IReadOnlyCollection<ConvaiTranscriptMode> modes)` | `void`                                       | 替换可供选择的转录模式集合。用于限制设置面板下拉框公开的模式      |

### `ConvaiRuntimeSettingsSnapshot`

由以下方法返回的不变结构体 `当前` 并包含在应用结果和变更事件中。所有字段都反映快照生成时刻的状态。

| 字段                            | 类型                     | 说明                    |
| ----------------------------- | ---------------------- | --------------------- |
| `PlayerDisplayName`           | `string`               | 转录气泡中显示的当前玩家显示名       |
| `TranscriptEnabled`           | `bool`                 | 是否启用转录 UI             |
| `NotificationsEnabled`        | `bool`                 | 是否启用场景内通知弹窗           |
| `PreferredMicrophoneDeviceId` | `string`               | 首选麦克风输入的设备 ID         |
| `TranscriptMode`              | `ConvaiTranscriptMode` | 当前转录显示模式（`聊天` 或 `字幕`) |

### `ConvaiRuntimeSettingsPatch`

传入 `Apply()`。任何留空的字段 `null` 在应用后保持不变。

| 字段                            | 类型                      | 说明                         |
| ----------------------------- | ----------------------- | -------------------------- |
| `PlayerDisplayName`           | `string`                | 设置新的玩家显示名。 `null` = 无更改    |
| `TranscriptEnabled`           | `bool?`                 | 启用或禁用转录 UI。 `null` = 无更改   |
| `NotificationsEnabled`        | `bool?`                 | 启用或禁用通知。 `null` = 无更改      |
| `PreferredMicrophoneDeviceId` | `string`                | 设置首选麦克风设备 ID。 `null` = 无更改 |
| `TranscriptMode`              | `ConvaiTranscriptMode?` | 切换转录显示模式。 `null` = 无更改     |

### `ConvaiRuntimeSettingsApplyResult`

由以下内容返回 `Apply()` 是位于 `ResetToDefaults()`.

| 字段                  | 类型                                | 说明                              |
| ------------------- | --------------------------------- | ------------------------------- |
| `Success`           | `bool`                            | `true` 如果应用操作成功                 |
| `快照`                | `ConvaiRuntimeSettingsSnapshot`   | 应用后的最终设置状态                      |
| `AppliedMask`       | `ConvaiRuntimeSettingsChangeMask` | 实际更改字段的位掩码                      |
| `ValidationMessage` | `string`                          | 失败原因，当 `Success == false`。成功时为空 |

### `ConvaiRuntimeSettingsChanged`

传递给 `已更改` 订阅者的负载。

| 字段         | 类型                                | 说明            |
| ---------- | --------------------------------- | ------------- |
| `Previous` | `ConvaiRuntimeSettingsSnapshot`   | 更改前的设置状态      |
| `当前`       | `ConvaiRuntimeSettingsSnapshot`   | 更改后的设置状态      |
| `Mask`     | `ConvaiRuntimeSettingsChangeMask` | 指示哪些字段已更改的位掩码 |

### `ConvaiRuntimeSettingsChangeMask`

A `[Flags]` 在以下位置使用的枚举 `AppliedMask` 是位于 `ConvaiRuntimeSettingsChanged.Mask`。通过按位与比较来检测特定更改。

| 值                             | 说明         |
| ----------------------------- | ---------- |
| `无`                           | 没有字段更改     |
| `PlayerDisplayName`           | 玩家显示名已更改   |
| `TranscriptEnabled`           | 转录已启用状态已更改 |
| `NotificationsEnabled`        | 通知已启用状态已更改 |
| `PreferredMicrophoneDeviceId` | 麦克风选择已更改   |
| `TranscriptMode`              | 转录模式已更改    |
| `全部`                          | 所有字段       |

### 面板中的转录模式限制

该 **转录样式** 设置面板中的下拉框仅显示在 `SupportedTranscriptModes`中注册的模式。默认情况下， `SettingsPanelPresenter` 将其初始化为 `{ ConvaiTranscriptMode.Chat }` 仅此而已。

要在面板下拉框中公开其他模式，请在 `SetSupportedTranscriptModes()` 之前调用：

```csharp
if (ConvaiManager.ActiveManager.TryGetRuntimeSettingsService(out var settings))
{
    settings.SetSupportedTranscriptModes(new[]
    {
        ConvaiTranscriptMode.Chat,
        ConvaiTranscriptMode.Subtitle
    });
}
```

若要在完全绕过面板的情况下切换到字幕模式，请直接使用 `Apply()` ：

```csharp
settings.Apply(new ConvaiRuntimeSettingsPatch
{
    TranscriptMode = ConvaiTranscriptMode.Subtitle
});
```

请参见 [聊天和字幕模式](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/ui-and-presentation/transcript-ui/chat-and-subtitle-modes.md) 以了解完整的模式切换细节。

### 使用示例

#### 读取当前设置

```csharp
using Convai.Runtime.Components;
using Convai.Shared.Types;
using UnityEngine;

public class SettingsReader : MonoBehaviour
{
    private void Start()
    {
        if (ConvaiManager.ActiveManager.TryGetRuntimeSettingsService(out var settings))
        {
            ConvaiRuntimeSettingsSnapshot current = settings.Current;
            Debug.Log($"玩家名称：{current.PlayerDisplayName}");
            Debug.Log($"转录已开启：{current.TranscriptEnabled}");
            Debug.Log($"模式：{current.TranscriptMode}");
        }
    }
}
```

#### 应用设置补丁

```csharp
if (ConvaiManager.ActiveManager.TryGetRuntimeSettingsService(out var settings))
{
    var result = settings.Apply(new ConvaiRuntimeSettingsPatch
    {
        PlayerDisplayName = "Dr. Kaan",
        TranscriptEnabled = true,
        TranscriptMode = ConvaiTranscriptMode.Subtitle
    });

    如果 !result.Success
        Debug.LogWarning($"设置应用失败：{result.ValidationMessage}");
}
```

#### 响应设置更改

```csharp
using Convai.Runtime.Components;
using Convai.Shared.Abstractions;
using Convai.Shared.Types;
using UnityEngine;

public class SettingsChangeReactor : MonoBehaviour
{
    private IConvaiRuntimeSettingsService _settings;

    private void OnEnable()
    {
        if (ConvaiManager.ActiveManager.TryGetRuntimeSettingsService(out _settings))
            _settings.Changed += OnSettingsChanged;
    }

    private void OnDisable()
    {
        if (_settings != null)
            _settings.Changed -= OnSettingsChanged;
    }

    private void OnSettingsChanged(ConvaiRuntimeSettingsChanged changed)
    {
        if ((changed.Mask & ConvaiRuntimeSettingsChangeMask.PreferredMicrophoneDeviceId) != 0)
        {
            Debug.Log($"麦克风已更改为：{changed.Current.PreferredMicrophoneDeviceId}");
            ApplyMicrophoneChange(changed.Current.PreferredMicrophoneDeviceId);
        }

        if ((changed.Mask & ConvaiRuntimeSettingsChangeMask.PlayerDisplayName) != 0)
        {
            UpdatePlayerNameDisplay(changed.Current.PlayerDisplayName);
        }
    }
}
```

#### 分析 — 跟踪设置更改

培训平台会记录学员何时更改其麦克风设备，以进行会话质量分析：

```csharp
private void OnSettingsChanged(ConvaiRuntimeSettingsChanged changed)
{
    if ((changed.Mask & ConvaiRuntimeSettingsChangeMask.PreferredMicrophoneDeviceId) != 0)
    {
        AnalyticsTracker.LogEvent("microphone_changed", new Dictionary<string, object>
        {
            { "previous", changed.Previous.PreferredMicrophoneDeviceId },
            { "current", changed.Current.PreferredMicrophoneDeviceId }
        });
    }
}
```

### 故障排查

| 症状                              | 可能原因           | 修复                                                                                       |
| ------------------------------- | -------------- | ---------------------------------------------------------------------------------------- |
| `Apply()` 返回 `Success == false` | 验证失败           | 检查 `result.ValidationMessage` 原因是                                                        |
| `已更改` 事件未触发                     | 未订阅，或在设置更改后才订阅 | 在以下位置订阅 `OnEnable` 在会话开始前                                                                |
| `ResetToDefaults()` 未检查结果       | 忽略返回值          | `ResetToDefaults()` 返回 `ConvaiRuntimeSettingsApplyResult` — 检查 `result.Success` 如果需要验证重置 |

### 下一步

{% content-ref url="/pages/dddf624ca0ae7ec32afa0c9e601f2cb7c7ab2b6a" %}
[设置面板](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/ui-and-presentation/settings-panel.md)
{% endcontent-ref %}

{% content-ref url="/pages/6695eb978b08dbf5023b367d38af0912574c4f52" %}
[聊天与字幕模式](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/ui-and-presentation/transcript-ui/chat-and-subtitle-modes.md)
{% endcontent-ref %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/ui-and-presentation/settings-panel/runtime-settings-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
