Release DLL-only UPM package v0.1.8

This commit is contained in:
su 2026-08-20 16:51:04 +08:00
parent eabd0e8597
commit d3fe91302a
6 changed files with 543 additions and 265 deletions

View File

@ -1,5 +1,12 @@
# Changelog
## 0.1.8
- Added detailed API documentation for result codes, face state codes, module statuses, directions, image DPI, feature types, bio types, configuration enums, model fields, license statuses, and license features.
- Added configuration documentation for auto-verify exclusive command policies and runtime status code entry points.
- Updated `FaceModuleManager.Instance` to lazily create and open the manager during Play Mode.
- Added read-only `FaceModuleManager` Inspector config display and an Editor menu for creating or selecting the scene manager.
## 0.1.7
- Fixed Unity runtime license binding so cached application parameters are used safely outside the Unity main thread.

View File

@ -1,188 +1,241 @@
# SDK API Reference
# SI-M1 Face SDK 接口文档
中文说明见 [SDK_API_Reference.zh-CN.md](SDK_API_Reference.zh-CN.md).
本文列出 SDK 对业务层推荐使用的公开 API。命名空间统一为 `Aisu.SIM1.Face.*`。
This document lists the business-level API exposed by `xin.aisu.si-m1.face`.
## 1. 命名空间
## Namespaces
| Namespace | Description |
| 命名空间 | 说明 |
|---|---|
| `Aisu.SIM1.Face.Core` | Manager, settings, callback adapter, logging, main-thread dispatch |
| `Aisu.SIM1.Face.Commands` | Business services, command service, encryption adapter |
| `Aisu.SIM1.Face.Protocol` | Protocol enums, packet build/parse helpers, encoding helpers |
| `Aisu.SIM1.Face.Transport` | Transport interface, serial transport, mock transport |
| `Aisu.SIM1.Face.Models` | Reply, note, user, verification, enrollment, image, and UVC models |
| `Aisu.SIM1.Face.Core` | Manager、配置、回调适配、日志、主线程调度 |
| `Aisu.SIM1.Face.Commands` | 业务服务、命令服务、加密接口 |
| `Aisu.SIM1.Face.Protocol` | 协议枚举、封包、拆包、编码工具 |
| `Aisu.SIM1.Face.Transport` | 通信接口、串口、Mock |
| `Aisu.SIM1.Face.Models` | Reply、Note、用户、验证、录入、图片、UVC 等模型 |
## FaceModuleManager
## 2. FaceModuleManager
Use `FaceModuleManager` as the recommended single entry point:
`FaceModuleManager` 是 SDK 推荐的统一入口。
```csharp
using Aisu.SIM1.Face.Core;
```
### Properties
### 属性
| Property | Type | Description |
| 属性 | 类型 | 说明 |
|---|---|---|
| `Basic` | `FaceBasicService` | Basic module commands |
| `Verify` | `FaceVerifyService` | Face verification service |
| `Enrollment` | `FaceEnrollmentService` | Face enrollment service |
| `Users` | `FaceUserService` | User management service |
| `QrCode` | `FaceQrCodeService` | QR code service |
| `Images` | `FaceImageService` | Image capture and photo enrollment service |
| `Features` | `FaceFeatureService` | Feature read/write service |
| `Uvc` | `FaceUvcService` | UVC and advanced parameter service |
| `Encryption` | `FaceEncryptionService` | Encryption service |
| `Callback` | `FaceModuleCallbackAdapter` | Callback-style API adapter |
| `IsOpen` | `bool` | Whether the transport is open |
| `IsReady` | `bool` | Whether READY has been received |
| `CurrentStatus` | `FaceModuleStatus` | Current module status |
| `LastError` | `string` | Latest error message |
| `CurrentCommand` | `string` | Current command name |
| `Config` | `FaceModuleConfig` | Current runtime config |
| `Settings` | `FaceSdkSettings` | Bound settings asset |
| `Basic` | `FaceBasicService` | 基础命令服务 |
| `Verify` | `FaceVerifyService` | 人脸验证服务 |
| `Enrollment` | `FaceEnrollmentService` | 人脸录入服务 |
| `Users` | `FaceUserService` | 用户管理服务 |
| `QrCode` | `FaceQrCodeService` | 二维码服务 |
| `Images` | `FaceImageService` | 图片抓拍与照片注册服务 |
| `Features` | `FaceFeatureService` | 特征读写服务 |
| `Uvc` | `FaceUvcService` | UVC 和高级参数服务 |
| `Encryption` | `FaceEncryptionService` | 加密相关服务 |
| `Callback` | `FaceModuleCallbackAdapter` | 回调式 API 适配 |
| `IsOpen` | `bool` | 通信是否打开 |
| `IsReady` | `bool` | 是否收到 READY |
| `CurrentStatus` | `FaceModuleStatus` | 当前模组状态 |
| `LastError` | `string` | 最近错误文本 |
| `CurrentCommand` | `string` | 当前命令名 |
| `Config` | `FaceModuleConfig` | 当前运行配置 |
| `Settings` | `FaceSdkSettings` | 当前绑定配置资产 |
### Methods
### 方法
| Method | Description |
| 方法 | 说明 |
|---|---|
| `ConfigureTransport(IFaceModuleTransport transport)` | Inject a custom transport |
| `Configure(bool useMockInEditor, string portName, int baudRate)` | Quick configuration for legacy code |
| `ApplySettings(FaceSdkSettings sdkSettings)` | Apply ScriptableObject settings and rebuild transport |
| `Open()` | Open transport |
| `Close()` | Stop active face operations and close transport |
| `CloseAsync()` | Stop active face operations and close transport asynchronously |
| `StopFaceOperationAsync()` | Stop auto verify or reset the current face flow |
| `StartAutoVerifyAsync(byte timeout)` | Start auto verify and return the control command result |
| `StopAutoVerifyAsync(byte timeout = 1)` | Stop auto verify and return the control command result |
| `WaitReadyAsync(int timeoutMs = 5000)` | Wait for READY note |
| `ProbeReadyByStatusAsync()` | Query status and mark manager ready |
| `SendRawBytes(byte[] bytes)` | Send raw protocol bytes |
| `RefreshStatus()` | Asynchronously refresh `CurrentStatus` |
| `ConfigureTransport(IFaceModuleTransport transport)` | 注入自定义通信层 |
| `Configure(bool useMockInEditor, string portName, int baudRate)` | 兼容旧代码的快速配置入口 |
| `ApplySettings(FaceSdkSettings sdkSettings)` | 应用 ScriptableObject 配置并重建 transport |
| `Open()` | 打开通信 |
| `Close()` | 同步安全关闭硬件流程并关闭串口 |
| `CloseAsync()` | 异步安全关闭硬件流程并关闭串口 |
| `StopFaceOperationAsync()` | 停止当前人脸流程,优先关闭自动验证 |
| `StartAutoVerifyAsync(byte timeout)` | 开启自动验证,返回开关命令结果 |
| `StopAutoVerifyAsync(byte timeout = 1)` | 关闭自动验证,返回开关命令结果 |
| `WaitReadyAsync(int timeoutMs = 5000)` | 等待 READY NOTE |
| `ProbeReadyByStatusAsync()` | 主动查询状态并标记 READY |
| `SendRawBytes(byte[] bytes)` | 发送原始协议 bytes |
| `RefreshStatus()` | 异步刷新 `CurrentStatus` |
### Events
真实串口运行前会自动校验 SDK 授权。授权文件默认路径:
| Event | Description |
```text
Assets/StreamingAssets/si-m1_face.dat
```
### 事件
| 事件 | 说明 |
|---|---|
| `OnReady` | First READY event |
| `OnStatusChanged(FaceModuleStatus)` | Module status changed |
| `OnReplyReceived(FaceReply)` | REPLY packet received |
| `OnNoteReceived(FaceNote)` | NOTE packet received |
| `OnFaceStateUpdated(FaceFaceStateNote)` | Face state NOTE received |
| `OnAutoVerifyResult(FaceAutoVerifyResult)` | Auto verify result NOTE received |
| `OnQrCodeReceived(string)` | QR code NOTE received |
| `OnFeatureReceived(byte[])` | Feature data packet received |
| `OnDataPacketReceived(FacePacket)` | Image/template data packet received |
| `OnError(FaceResultCode, string)` | Error reported |
| `OnRawLog(string)` | Raw TX/RX log |
| `OnReady` | 首次 READY |
| `OnStatusChanged(FaceModuleStatus)` | 当前状态变化 |
| `OnReplyReceived(FaceReply)` | 收到 REPLY 包 |
| `OnNoteReceived(FaceNote)` | 收到 NOTE 包 |
| `OnFaceStateUpdated(FaceFaceStateNote)` | 收到人脸状态 NOTE |
| `OnAutoVerifyResult(FaceAutoVerifyResult)` | 收到自动验证识别结果 NOTE |
| `OnQrCodeReceived(string)` | 收到二维码 NOTE |
| `OnFeatureReceived(byte[])` | 收到读取特征数据包 |
| `OnDataPacketReceived(FacePacket)` | 收到 ImageOrTemplate 数据包 |
| `OnError(FaceResultCode, string)` | 错误上报 |
| `OnRawLog(string)` | 原始 TX / RX 日志 |
## Async Services
## 3. 基础服务 FaceBasicService
### FaceBasicService
访问路径:
Access path: `manager.Basic`
```csharp
manager.Basic
```
| Method | Return | Description |
| 方法 | 返回 | 说明 |
|---|---|---|
| `ResetAsync()` | `Task<FaceReply>` | Reset module |
| `FaceResetAsync()` | `Task<FaceReply>` | Cancel current face flow |
| `GetStatusAsync()` | `Task<FaceModuleStatus>` | Get module status |
| `GetVersionAsync()` | `Task<string>` | Get firmware version |
| `GetSnAsync()` | `Task<string>` | Get device serial number |
| `SetDemoModeAsync(bool enable)` | `Task<FaceReply>` | Set Demo Mode |
| `UpgradeFirmwareAsync()` | `Task<FaceReply>` | Start firmware upgrade command |
| `ResetAsync()` | `Task<FaceReply>` | 复位模组 |
| `FaceResetAsync()` | `Task<FaceReply>` | 取消当前人脸流程 |
| `GetStatusAsync()` | `Task<FaceModuleStatus>` | 获取模组状态 |
| `GetVersionAsync()` | `Task<string>` | 获取固件版本 |
| `GetSnAsync()` | `Task<string>` | 获取设备序列号 |
| `SetDemoModeAsync(bool enable)` | `Task<FaceReply>` | 设置 Demo Mode |
| `UpgradeFirmwareAsync()` | `Task<FaceReply>` | 启动固件升级命令 |
### FaceVerifyService
## 4. 验证服务 FaceVerifyService
Access path: `manager.Verify`
访问路径:
| Method | Return | Description |
```csharp
manager.Verify
```
| 方法 | 返回 | 说明 |
|---|---|---|
| `VerifyAsync(byte timeout, byte maxRecognitionTimes = 30)` | `Task<FaceVerifyResult>` | Run one face verification |
| `AutoVerifyAsync(bool enable, byte timeout)` | `Task<FaceReply>` | Low-level auto verify control command |
| `VerifyAsync(byte timeout, byte maxRecognitionTimes = 30)` | `Task<FaceVerifyResult>` | 单次人脸验证 |
| `AutoVerifyAsync(bool enable, byte timeout)` | `Task<FaceReply>` | 底层自动验证开关命令,只表示开关命令 ACK |
For application code, prefer `FaceModuleManager.StartAutoVerifyAsync()` and `FaceModuleManager.StopAutoVerifyAsync()`. Recognition results are delivered through `OnAutoVerifyResult`.
推荐业务层使用 `FaceModuleManager.StartAutoVerifyAsync()` 和 `FaceModuleManager.StopAutoVerifyAsync()` 控制自动验证,识别结果通过 `OnAutoVerifyResult` 获取。
### FaceEnrollmentService
```csharp
var control = await manager.StartAutoVerifyAsync(10);
if (control.Success)
{
manager.OnAutoVerifyResult += result =>
{
Debug.Log("自动验证结果: " + result.ResultCode);
};
}
```
Access path: `manager.Enrollment`
`StartAutoVerifyAsync()` / `StopAutoVerifyAsync()` 的返回值是 `FaceAutoVerifyControlResult`,表示开启或关闭命令是否成功,不表示识别结果。
| Method | Return | Description |
## 5. 录入服务 FaceEnrollmentService
访问路径:
```csharp
manager.Enrollment
```
| 方法 | 返回 | 说明 |
|---|---|---|
| `EnrollAsync(bool admin, string userName, FaceDirection direction, byte timeout)` | `Task<FaceEnrollResult>` | Interactive multi-direction enrollment |
| `EnrollSingleAsync(bool admin, string userName, byte timeout)` | `Task<FaceEnrollResult>` | Single-frame enrollment |
| `EnrollIntegratedAsync(bool admin, string userName, FaceDirection direction, byte timeout, bool singleFrame = false, bool duplicateCheck = true)` | `Task<FaceEnrollResult>` | Integrated enrollment |
| `EnrollSnapFaceImageAsync(bool admin, string userName)` | `Task<FaceEnrollResult>` | Capture face image and enroll |
| `EnrollAsync(bool admin, string userName, FaceDirection direction, byte timeout)` | `Task<FaceEnrollResult>` | 交互式多方向录入 |
| `EnrollSingleAsync(bool admin, string userName, byte timeout)` | `Task<FaceEnrollResult>` | 单帧录入 |
| `EnrollIntegratedAsync(bool admin, string userName, FaceDirection direction, byte timeout, bool singleFrame = false, bool duplicateCheck = true)` | `Task<FaceEnrollResult>` | 集成式录入 |
| `EnrollSnapFaceImageAsync(bool admin, string userName)` | `Task<FaceEnrollResult>` | 抓拍人脸后注册 |
### FaceUserService
## 6. 用户服务 FaceUserService
Access path: `manager.Users`
访问路径:
| Method | Return | Description |
```csharp
manager.Users
```
| 方法 | 返回 | 说明 |
|---|---|---|
| `DeleteUserAsync(int userId)` | `Task<FaceReply>` | Delete a user |
| `DeleteAllAsync()` | `Task<FaceReply>` | Delete all users |
| `GetUserInfoAsync(int userId)` | `Task<FaceUserInfo>` | Query one user |
| `GetAllUserIdsAsync()` | `Task<List<int>>` | Query all user IDs |
| `GetAllUserIds2Async()` | `Task<List<int>>` | Query all user IDs with extended command |
| `GetAllUserInfosAsync()` | `Task<List<FaceUserInfo>>` | Query all user details |
| `GetAllUserInfos2Async()` | `Task<List<FaceUserInfo>>` | Query all user details with extended command |
| `DeleteUserAsync(int userId)` | `Task<FaceReply>` | 删除指定用户 |
| `DeleteAllAsync()` | `Task<FaceReply>` | 删除全部用户 |
| `GetUserInfoAsync(int userId)` | `Task<FaceUserInfo>` | 查询用户信息 |
| `GetAllUserIdsAsync()` | `Task<List<int>>` | 查询用户 ID 列表 |
| `GetAllUserIds2Async()` | `Task<List<int>>` | 使用扩展命令查询用户 ID 列表 |
| `GetAllUserInfosAsync()` | `Task<List<FaceUserInfo>>` | 查询全部用户详情 |
| `GetAllUserInfos2Async()` | `Task<List<FaceUserInfo>>` | 使用扩展命令查询全部用户详情 |
### FaceQrCodeService
## 7. 二维码服务 FaceQrCodeService
Access path: `manager.QrCode`
访问路径:
| Method | Return | Description |
```csharp
manager.QrCode
```
| 方法 | 返回 | 说明 |
|---|---|---|
| `ScanQrCodeAsync(byte timeout)` | `Task<string>` | Scan QR code and return content |
| `ScanQrCodeAsync(byte timeout)` | `Task<string>` | 扫描二维码并返回内容 |
### FaceImageService
## 8. 图片服务 FaceImageService
Access path: `manager.Images`
访问路径:
| Method | Return | Description |
```csharp
manager.Images
```
| 方法 | 返回 | 说明 |
|---|---|---|
| `SnapUploadImageAsync()` | `Task<FaceImageResult>` | Capture normal image |
| `SnapUploadFaceImageAsync()` | `Task<FaceImageResult>` | Capture face image |
| `SnapUploadLargeImageAsync(ImageDpi dpi)` | `Task<FaceImageResult>` | Capture large image |
| `EnrollWithPhotoAsync(byte[] photoBytes, BioType type, string userName = null, bool duplicateCheck = true, Action<int, int> onProgress = null)` | `Task<FaceEnrollResult>` | Enroll with photo |
| `EnrollWithPhotoAndIdAsync(int userId, byte[] photoBytes, BioType type, string userName = null, bool duplicateCheck = true, Action<int, int> onProgress = null)` | `Task<FaceEnrollResult>` | Enroll photo with specified user ID |
| `SnapUploadImageAsync()` | `Task<FaceImageResult>` | 抓拍普通图片 |
| `SnapUploadFaceImageAsync()` | `Task<FaceImageResult>` | 抓拍人脸图片 |
| `SnapUploadLargeImageAsync(ImageDpi dpi)` | `Task<FaceImageResult>` | 抓拍大图 |
| `EnrollWithPhotoAsync(byte[] photoBytes, BioType type, string userName = null, bool duplicateCheck = true, Action<int, int> onProgress = null)` | `Task<FaceEnrollResult>` | 照片注册 |
| `EnrollWithPhotoAndIdAsync(int userId, byte[] photoBytes, BioType type, string userName = null, bool duplicateCheck = true, Action<int, int> onProgress = null)` | `Task<FaceEnrollResult>` | 指定用户 ID 照片注册 |
### FaceFeatureService
## 9. 特征服务 FaceFeatureService
Access path: `manager.Features`
访问路径:
| Method | Return | Description |
```csharp
manager.Features
```
| 方法 | 返回 | 说明 |
|---|---|---|
| `ReadFeatureAsync(int userId, FeatureType type)` | `Task<byte[]>` | Read user feature |
| `WriteFeatureAsync(byte[] featureBytes, FeatureType type, string userName = null, Action<int, int> onProgress = null)` | `Task<FaceEnrollResult>` | Write feature and enroll |
| `ReadFeatureAsync(int userId, FeatureType type)` | `Task<byte[]>` | 读取指定用户特征 |
| `WriteFeatureAsync(byte[] featureBytes, FeatureType type, string userName = null, Action<int, int> onProgress = null)` | `Task<FaceEnrollResult>` | 写入特征并注册 |
### FaceUvcService
## 10. UVC 和高级参数 FaceUvcService
Access path: `manager.Uvc`
访问路径:
| Method | Return | Description |
```csharp
manager.Uvc
```
| 方法 | 返回 | 说明 |
|---|---|---|
| `ReadUsbUvcParametersAsync()` | `Task<UsbUvcParameters>` | Read USB/UVC parameters |
| `SetUsbUvcParametersAsync(UsbUvcParameters parameters)` | `Task<FaceReply>` | Set USB/UVC parameters |
| `SetFaceLocationDisplayAsync(bool visible)` | `Task<FaceReply>` | Set face rectangle display |
| `SetRgbLevelAsync(byte level)` | `Task<FaceReply>` | Set RGB level |
| `SetDuplicateCheckAsync(bool enableCheck)` | `Task<FaceReply>` | Set duplicate check |
| `ReadDuplicateCheckAsync()` | `Task<bool>` | Read duplicate check state |
| `ReadUsbUvcParametersAsync()` | `Task<UsbUvcParameters>` | 读取 USB / UVC 参数 |
| `SetUsbUvcParametersAsync(UsbUvcParameters parameters)` | `Task<FaceReply>` | 设置 USB / UVC 参数 |
| `SetFaceLocationDisplayAsync(bool visible)` | `Task<FaceReply>` | 设置人脸框显示 |
| `SetRgbLevelAsync(byte level)` | `Task<FaceReply>` | 设置 RGB 阈值 |
| `SetDuplicateCheckAsync(bool enableCheck)` | `Task<FaceReply>` | 设置查重 |
| `ReadDuplicateCheckAsync()` | `Task<bool>` | 读取查重状态 |
### FaceEncryptionService
## 11. 加密服务 FaceEncryptionService
Access path: `manager.Encryption`
访问路径:
| Method | Return | Description |
```csharp
manager.Encryption
```
| 方法 | 返回 | 说明 |
|---|---|---|
| `SetReleaseEncryptionKeyAsync(byte[] key16)` | `Task<FaceReply>` | Set release encryption key |
| `SetDebugEncryptionKeyAsync(byte[] key16)` | `Task<FaceReply>` | Set debug encryption key |
| `InitEncryptionAsync(byte[] seed4, byte mode)` | `Task<FaceReply>` | Initialize encryption |
| `EnableEncryption(IFaceModuleCrypto crypto)` | `void` | Enable local crypto adapter |
| `DisableEncryption()` | `void` | Disable local crypto adapter |
| `SetReleaseEncryptionKeyAsync(byte[] key16)` | `Task<FaceReply>` | 设置 Release 加密密钥 |
| `SetDebugEncryptionKeyAsync(byte[] key16)` | `Task<FaceReply>` | 设置 Debug 加密密钥 |
| `InitEncryptionAsync(byte[] seed4, byte mode)` | `Task<FaceReply>` | 初始化加密流程 |
| `EnableEncryption(IFaceModuleCrypto crypto)` | `void` | 设置本地加密算法适配器 |
| `DisableEncryption()` | `void` | 关闭本地加密算法适配器 |
`IFaceModuleCrypto`:
```csharp
public interface IFaceModuleCrypto
@ -193,108 +246,239 @@ public interface IFaceModuleCrypto
}
```
## Callback API
## 12. 回调式 API
`FaceModuleManager.Callback` is useful for Unity UI, button events, legacy callback-style code, or workflows where `await` is inconvenient.
`FaceModuleManager.Callback` 适合 Unity Button、旧项目回调风格或不方便使用 `await` 的业务。
Callbacks use a consistent pattern:
```csharp
manager.Callback.Verify(
timeout: 10,
success: result => Debug.Log(result.UserId),
error: message => Debug.LogError(message));
```
- `success` is invoked on success.
- `error` receives an error message on failure.
- Photo enrollment and feature writing support `progress(current, total)`.
- Callbacks are dispatched back to the Unity main thread through `FaceModuleMainThreadDispatcher`.
回调特点:
### Lifecycle and Transport
- 所有 API 统一使用 `success` 和 `error`。
- 照片注册、特征写入支持 `progress(current, total)`。
- 回调会通过 `FaceModuleMainThreadDispatcher` 回到 Unity 主线程。
| Method | Success Callback | Description |
|---|---|---|
| `ConfigureTransport(IFaceModuleTransport transport, Action success, Action<string> error)` | `Action` | Inject custom transport |
| `Configure(bool useMockInEditor, string portName, int baudRate, Action success, Action<string> error)` | `Action` | Configure default transport parameters |
| `Open(Action success, Action<string> error)` | `Action` | Open transport |
| `Close(Action success, Action<string> error)` | `Action` | Close transport |
| `StopFaceOperation(Action success, Action<string> error)` | `Action` | Stop auto verify or reset current face flow |
| `SendRawBytes(byte[] bytes, Action success, Action<string> error)` | `Action` | Send raw bytes |
| `WaitReady(int timeoutMs, Action success, Action<string> error)` | `Action` | Wait for READY |
| `ProbeReadyByStatus(Action<FaceModuleStatus> success, Action<string> error)` | `Action<FaceModuleStatus>` | Probe status and mark ready |
## 13. 主要模型
### Basic Commands
| Method | Success Callback | Description |
|---|---|---|
| `Reset(Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Reset module |
| `FaceReset(Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Cancel current face flow |
| `GetStatus(Action<FaceModuleStatus> success, Action<string> error)` | `Action<FaceModuleStatus>` | Get module status |
| `GetVersion(Action<string> success, Action<string> error)` | `Action<string>` | Get firmware version |
| `GetSn(Action<string> success, Action<string> error)` | `Action<string>` | Get device serial number |
| `SetDemoMode(bool enable, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Set Demo Mode |
| `UpgradeFirmware(Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Start firmware upgrade |
### Verification and Enrollment
| Method | Success Callback | Description |
|---|---|---|
| `Verify(byte timeout, Action<FaceVerifyResult> success, Action<string> error, byte maxRecognitionTimes = 30)` | `Action<FaceVerifyResult>` | Run face verification |
| `AutoVerify(bool enable, byte timeout, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Low-level auto verify control command |
| `StartAutoVerify(byte timeout, Action<FaceAutoVerifyControlResult> success, Action<string> error)` | `Action<FaceAutoVerifyControlResult>` | Start auto verify |
| `StopAutoVerify(byte timeout, Action<FaceAutoVerifyControlResult> success, Action<string> error)` | `Action<FaceAutoVerifyControlResult>` | Stop auto verify |
| `Enroll(bool admin, string userName, FaceDirection direction, byte timeout, Action<FaceEnrollResult> success, Action<string> error)` | `Action<FaceEnrollResult>` | Interactive enrollment |
| `EnrollSingle(bool admin, string userName, byte timeout, Action<FaceEnrollResult> success, Action<string> error)` | `Action<FaceEnrollResult>` | Single-frame enrollment |
| `EnrollIntegrated(bool admin, string userName, FaceDirection direction, byte timeout, bool singleFrame, bool duplicateCheck, Action<FaceEnrollResult> success, Action<string> error)` | `Action<FaceEnrollResult>` | Integrated enrollment |
| `EnrollSnapFaceImage(bool admin, string userName, Action<FaceEnrollResult> success, Action<string> error)` | `Action<FaceEnrollResult>` | Capture face image and enroll |
### Users
| Method | Success Callback | Description |
|---|---|---|
| `DeleteUser(int userId, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Delete user |
| `DeleteAll(Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Delete all users |
| `GetUserInfo(int userId, Action<FaceUserInfo> success, Action<string> error)` | `Action<FaceUserInfo>` | Query one user |
| `GetAllUserIds(Action<List<int>> success, Action<string> error)` | `Action<List<int>>` | Query all user IDs |
| `GetAllUserIds2(Action<List<int>> success, Action<string> error)` | `Action<List<int>>` | Query all user IDs with extended command |
| `GetAllUserInfos(Action<List<FaceUserInfo>> success, Action<string> error)` | `Action<List<FaceUserInfo>>` | Query all user details |
| `GetAllUserInfos2(Action<List<FaceUserInfo>> success, Action<string> error)` | `Action<List<FaceUserInfo>>` | Query all user details with extended command |
### QR Code, Images, and Features
| Method | Success Callback | Description |
|---|---|---|
| `ScanQrCode(byte timeout, Action<string> success, Action<string> error)` | `Action<string>` | Scan QR code |
| `SnapUploadImage(Action<FaceImageResult> success, Action<string> error)` | `Action<FaceImageResult>` | Capture normal image |
| `SnapUploadFaceImage(Action<FaceImageResult> success, Action<string> error)` | `Action<FaceImageResult>` | Capture face image |
| `SnapUploadLargeImage(ImageDpi dpi, Action<FaceImageResult> success, Action<string> error)` | `Action<FaceImageResult>` | Capture large image |
| `EnrollWithPhoto(byte[] photoBytes, BioType type, string userName, bool duplicateCheck, Action<FaceEnrollResult> success, Action<string> error, Action<int, int> progress = null)` | `Action<FaceEnrollResult>` | Enroll with photo |
| `EnrollWithPhotoAndId(int userId, byte[] photoBytes, BioType type, string userName, bool duplicateCheck, Action<FaceEnrollResult> success, Action<string> error, Action<int, int> progress = null)` | `Action<FaceEnrollResult>` | Enroll photo with specified user ID |
| `ReadFeature(int userId, FeatureType type, Action<byte[]> success, Action<string> error)` | `Action<byte[]>` | Read user feature |
| `WriteFeature(byte[] featureBytes, FeatureType type, string userName, Action<FaceEnrollResult> success, Action<string> error, Action<int, int> progress = null)` | `Action<FaceEnrollResult>` | Write feature and enroll |
### UVC and Encryption
| Method | Success Callback | Description |
|---|---|---|
| `ReadUsbUvcParameters(Action<UsbUvcParameters> success, Action<string> error)` | `Action<UsbUvcParameters>` | Read USB/UVC parameters |
| `SetUsbUvcParameters(UsbUvcParameters parameters, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Set USB/UVC parameters |
| `SetFaceLocationDisplay(bool visible, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Set face rectangle display |
| `SetRgbLevel(byte level, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Set RGB level |
| `SetDuplicateCheck(bool enableCheck, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Set duplicate check |
| `ReadDuplicateCheck(Action<bool> success, Action<string> error)` | `Action<bool>` | Read duplicate check state |
| `SetReleaseEncryptionKey(byte[] key16, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Set release encryption key |
| `SetDebugEncryptionKey(byte[] key16, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Set debug encryption key |
| `InitEncryption(byte[] seed4, byte mode, Action<FaceReply> success, Action<string> error)` | `Action<FaceReply>` | Initialize encryption |
| `EnableEncryption(IFaceModuleCrypto crypto, Action success, Action<string> error)` | `Action` | Enable local crypto adapter |
| `DisableEncryption(Action success, Action<string> error)` | `Action` | Disable local crypto adapter |
## Main Models
| Type | Description |
| 类型 | 说明 |
|---|---|
| `FaceReply` | REPLY packet parse result |
| `FaceNote` | NOTE packet parse result |
| `FaceFaceStateNote` | Face state NOTE |
| `FaceAutoVerifyResult` | Auto verify recognition result |
| `FaceAutoVerifyControlResult` | Auto verify start/stop command result |
| `FaceUserInfo` | User ID, name, and admin flag |
| `FaceVerifyResult` | Verification result, user info, unlock status |
| `FaceEnrollResult` | Enrollment result, user ID, direction |
| `FaceImageResult` | Image bytes, `Texture2D`, user ID |
| `UsbUvcParameters` | USB/UVC parameters |
| `FaceCommandException` | Exception thrown for unsuccessful command replies |
| `FaceReply` | REPLY 包解析结果 |
| `FaceNote` | NOTE 包解析结果 |
| `FaceFaceStateNote` | 人脸状态 NOTE |
| `FaceUserInfo` | 用户 ID、姓名、管理员标记 |
| `FaceVerifyResult` | 验证结果、用户信息、开锁状态 |
| `FaceAutoVerifyResult` | 自动验证识别结果 |
| `FaceAutoVerifyControlResult` | 自动验证开启/关闭命令结果 |
| `FaceEnrollResult` | 录入结果、用户 ID、方向 |
| `FaceImageResult` | 图片 bytes、Texture2D、用户 ID |
| `UsbUvcParameters` | USB / UVC 参数 |
| `FaceCommandException` | 底层命令 REPLY 非成功时抛出的异常 |
高层业务 Result 类型统一使用 `Success` 和 `ResultCode`。`FaceReply` 是底层 REPLY 模型,也统一只暴露 `Success` 和 `ResultCode`。
### 13.1 常用模型字段
| 类型 | 字段 | 说明 |
|---|---|---|
| `FaceReply` | `Mid` | 对应的命令 ID |
| `FaceReply` | `Success` | `ResultCode == FaceResultCode.Success` |
| `FaceReply` | `ResultCode` | 模组返回结果码 |
| `FaceReply` | `Data` | REPLY 业务数据,不包含命令 ID 和结果码 |
| `FaceNote` | `Nid` | NOTE 类型 |
| `FaceNote` | `Data` | NOTE 业务数据,不包含 NOTE ID |
| `FaceFaceStateNote` | `State` | 人脸状态码 |
| `FaceFaceStateNote` | `Left` / `Top` / `Right` / `Bottom` | 人脸框坐标 |
| `FaceFaceStateNote` | `Yaw` / `Pitch` / `Roll` | 人脸姿态角 |
| `FaceUserInfo` | `UserId` | 用户 ID |
| `FaceUserInfo` | `UserName` | 用户名 |
| `FaceUserInfo` | `IsAdmin` | 是否管理员 |
| `FaceVerifyResult` | `Success` / `ResultCode` | 验证是否成功及结果码 |
| `FaceVerifyResult` | `UserId` / `UserName` / `IsAdmin` | 验证成功时的用户信息 |
| `FaceVerifyResult` | `UnlockStatus` | 模组返回的开锁状态 |
| `FaceAutoVerifyResult` | `Success` / `ResultCode` | 自动验证 NOTE 的识别结果 |
| `FaceAutoVerifyResult` | `VerifyResult` | 成功时解析出的验证结果详情 |
| `FaceAutoVerifyControlResult` | `Success` / `ResultCode` | 自动验证开关命令结果 |
| `FaceAutoVerifyControlResult` | `Enabled` | 本次命令目标状态 |
| `FaceAutoVerifyControlResult` | `Reply` | 底层开关命令 REPLY |
| `FaceEnrollResult` | `Success` / `ResultCode` | 录入是否成功及结果码 |
| `FaceEnrollResult` | `UserId` | 录入成功后分配或写入的用户 ID |
| `FaceEnrollResult` | `Direction` | 录入方向 |
| `FaceImageResult` | `Success` / `ResultCode` | 图片命令是否成功及结果码 |
| `FaceImageResult` | `UserId` | 照片注册相关用户 ID |
| `FaceImageResult` | `Bytes` | 图片原始 bytes |
| `FaceImageResult` | `Texture` | Unity `Texture2D` |
| `UsbUvcParameters` | `UsbType` | USB 输出类型 |
| `UsbUvcParameters` | `BitrateMbps` | 码率,单位 Mbps |
| `UsbUvcParameters` | `MjpgQuality` | MJPG 质量 |
| `UsbUvcParameters` | `Mirror` | 是否镜像 |
| `UsbUvcParameters` | `Rotate180` | 是否旋转 180 度 |
### 13.2 FaceResultCode 结果码
`FaceResultCode` 会出现在 `FaceReply.ResultCode`、高层业务 Result、`OnError`、`FaceCommandException.ResultCode` 中。可使用 `FaceProtocolEncoding.ResultMessage(code)` 获取中文提示。
| 值 | 名称 | 说明 |
|---:|---|---|
| 0 | `Success` | 成功 |
| 1 | `Rejected` | 模组拒绝命令 |
| 2 | `Aborted` | 操作已终止 |
| 4 | `CameraOpenFailed` | 相机打开失败 |
| 5 | `UnknownReason` | 未知错误 |
| 6 | `InvalidParam` | 参数无效 |
| 7 | `NoMemory` | 内存不足 |
| 8 | `UnknownUser` | 未找到用户或没有已录入用户 |
| 9 | `MaxUser` | 超过最大用户数量 |
| 10 | `FaceEnrolled` | 人脸已录入 |
| 12 | `LivenessCheckFailed` | 活体检测失败 |
| 13 | `Timeout` | 操作超时 |
| 14 | `AuthorizationFailed` | 模组侧授权失败 |
| 19 | `ReadFileFailed` | 读文件失败 |
| 20 | `WriteFileFailed` | 写文件失败 |
| 21 | `NoEncrypt` | 通信未加密 |
| 23 | `NoRgbImage` | RGB 图像未就绪 |
| 24 | `JpgPhotoTooLarge` | JPG 照片过大 |
| 25 | `JpgPhotoTooSmall` | JPG 照片过小 |
| 26 | `DetectQr` | 识别过程中检测到二维码 |
### 13.3 FaceStateCode 人脸状态码
`FaceStateCode` 来自 `OnFaceStateUpdated(FaceFaceStateNote)`,主要用于录入、检测和 UI 引导。可使用 `FaceProtocolEncoding.FaceStateMessage(code)` 获取中文提示。
| 值 | 名称 | 说明 |
|---:|---|---|
| 0 | `Normal` | 人脸正常 |
| 1 | `NoFace` | 未检测到人脸 |
| 2 | `TooUp` | 人脸太靠上 |
| 3 | `TooDown` | 人脸太靠下 |
| 4 | `TooLeft` | 人脸太靠左 |
| 5 | `TooRight` | 人脸太靠右 |
| 6 | `Far` | 距离太远 |
| 7 | `Close` | 距离太近 |
| 8 | `EyebrowOcclusion` | 眉毛遮挡 |
| 9 | `EyeOcclusion` | 眼睛遮挡 |
| 10 | `FaceOcclusion` | 脸部遮挡 |
| 11 | `DirectionError` | 录入方向错误 |
| 12 | `EyeCloseStatusOpenEye` | 闭眼检测中发现睁眼 |
| 13 | `EyeCloseStatus` | 当前为闭眼状态 |
| 14 | `EyeCloseUnknownStatus` | 无法判定睁闭眼状态 |
| 128 | `PalmDetected` | 检测到手掌信息 |
### 13.4 业务常用枚举
| 枚举 | 值 | 说明 |
|---|---|---|
| `FaceModuleStatus` | `Standby = 0` | 模组待机 |
| `FaceModuleStatus` | `Busy = 1` | 模组忙碌 |
| `FaceModuleStatus` | `Error = 2` | 模组错误 |
| `FaceModuleStatus` | `Invalid = 3` | SDK 未知或无效状态 |
| `FaceDirection` | `Undefined = 0x00` | 未定义方向 |
| `FaceDirection` | `Middle = 0x01` | 正脸 |
| `FaceDirection` | `Right = 0x02` | 向右 |
| `FaceDirection` | `Left = 0x04` | 向左 |
| `FaceDirection` | `Down = 0x08` | 向下 |
| `FaceDirection` | `Up = 0x10` | 向上 |
| `BioType` | `NormalPhoto = 0` | 普通照片 |
| `BioType` | `EncryptedPhoto = 1` | 加密照片 |
| `BioType` | `NormalFeature = 2` | 普通特征 |
| `BioType` | `CompressedFeature = 3` | 压缩特征 |
| `FeatureType` | `ColorFace = 1` | 彩色人脸特征 |
| `FeatureType` | `ColorAndIrFace = 2` | 彩色加红外人脸特征 |
| `FeatureType` | `Palm = 3` | 手掌特征 |
| `ImageDpi` | `Dpi480x640 = 0` | 480x640 大图 |
| `ImageDpi` | `Dpi600x800 = 1` | 600x800 大图 |
| `ImageDpi` | `Dpi1200x1600 = 2` | 1200x1600 大图 |
### 13.5 配置枚举
| 枚举 | 值 | 说明 |
|---|---|---|
| `FaceTransportMode` | `Auto = 0` | 默认通信模式,当前串口实现下等价于串口,Editor 可按 Mock 配置切换 |
| `FaceTransportMode` | `SerialPort = 1` | 强制使用串口通信 |
| `FaceTransportMode` | `Mock = 3` | 使用 Mock 模组 |
| `FaceExclusiveCommandPolicy` | `RejectWhenAutoVerifyEnabled = 0` | 自动验证开启时拒绝独占命令 |
| `FaceExclusiveCommandPolicy` | `StopAutoVerify = 1` | 独占命令前自动关闭自动验证 |
| `FaceExclusiveCommandPolicy` | `Ignore = 2` | 不处理自动验证状态,由业务自行保证不冲突 |
## 14. 协议和通信底层
业务层通常不需要直接使用底层 API。需要协议调试或自定义通信时可使用:
| 类型 | 说明 |
|---|---|
| `FacePacketBuilder` | 封包 |
| `FacePacketParser` | 拆包 |
| `FaceProtocolEncoding` | 用户名、ID、结果文本等编码工具 |
| `IFaceModuleTransport` | 通信接口 |
| `SerialPortTransport` | 串口实现 |
| `MockFaceModuleTransport` | Mock 实现 |
## 15. 授权 API
命名空间:
```csharp
using Aisu.SIM1.Face.Core;
```
| 类型 | 说明 |
|---|---|
| `FaceLicenseManager` | 加载、验证授权 token,查询授权状态 |
| `FaceLicensePayload` | 授权 payload 数据 |
| `FaceLicenseStatus` | 授权状态枚举 |
| `FaceLicenseException` | 授权异常 |
| `FaceLicenseFeatures` | 功能授权常量 |
| `FaceUnityRuntimeBinding` | 读取 `identifier`、`companyName`、`productName`、`version`、`unityVersion` |
常用方法:
| 方法 | 说明 |
|---|---|
| `FaceLicenseManager.LoadAndVerify()` | 读取默认授权文件并验签 |
| `FaceLicenseManager.VerifyOrThrow()` | 授权无效时抛出异常 |
| `FaceLicenseManager.VerifyFeatureOrThrow(string feature)` | 功能未授权时抛出异常 |
| `FaceLicenseManager.IsFeatureEnabled(string feature)` | 查询功能是否授权 |
| `FaceLicenseVerifier.VerifyToken(string token)` | 验签并校验授权 payload |
| `FaceLicenseVerifier.ValidatePayload(FaceLicensePayload payload)` | 校验 payload 字段、有效期、功能和 Unity 绑定 |
| `FaceLicenseVerifier.GetBeijingNow()` | 获取 SDK 授权使用的当前北京时间 |
| `FaceLicenseVerifier.FormatBeijingTime(DateTimeOffset value)` | 格式化授权北京时间字符串 |
| `FaceLicenseVerifier.GetRemainingDays(FaceLicensePayload payload)` | 计算授权剩余天数 |
### 15.1 FaceLicenseStatus
| 值 | 名称 | 说明 |
|---:|---|---|
| 0 | `Unknown` | 尚未验证或状态未知 |
| 1 | `Valid` | 授权有效 |
| 2 | `MissingFile` | 授权文件不存在 |
| 3 | `InvalidFormat` | 授权格式无效 |
| 4 | `InvalidSignature` | 授权签名无效 |
| 5 | `ProductMismatch` | 产品 ID 不匹配 |
| 6 | `BindingMismatch` | Unity 绑定参数不匹配 |
| 7 | `Expired` | 授权已过期 |
| 8 | `FeatureDenied` | 功能未授权 |
| 9 | `PublicKeyInvalid` | SDK 公钥无效 |
| 10 | `ReadFailed` | 授权读取失败 |
| 11 | `NotYetValid` | 授权尚未生效 |
### 15.2 FaceLicenseFeatures
| 名称 | 说明 |
|---|---|
| `SerialRuntime` | 串口运行时 |
| `Basic` | 基础命令 |
| `Verify` | 人脸验证和自动验证 |
| `Enroll` | 人脸录入 |
| `UserManage` | 用户管理 |
| `QrCode` | 二维码 |
| `Image` | 图片抓拍、照片注册 |
| `Feature` | 特征读写 |
| `Uvc` | UVC 和高级参数 |
| `Encryption` | 加密通信 |
| `Firmware` | 固件升级 |
Runtime 不提供 token 签发 API,也不提供公钥覆盖 API。授权签发只应存在于内部 Editor DLL 或独立授权工具中。

View File

@ -1,75 +1,162 @@
# SDK Configuration
# SI-M1 Face SDK 配置与 Editor 工具
中文说明见 [SDK_Configuration.zh-CN.md](SDK_Configuration.zh-CN.md).
SDK 使用 `FaceSdkSettings` 作为推荐配置方式。该配置是 `ScriptableObject`,可在项目中复用,并可同步到场景中的 `FaceModuleManager`。
The SDK uses `FaceSdkSettings` as the recommended configuration asset. `FaceModuleManager` can read this asset and synchronize the values into its runtime config.
## 1. 默认配置资产
## Default Settings Asset
默认路径:
```text
Assets/Resources/AISU/SI-M1 Face SDK/FaceSdkSettings.asset
```
Open `AISU/SI-M1 Face SDK/Settings` to load, edit, and save the asset.
打开菜单 `AISU/SI-M1 Face SDK/Settings` 后,Editor 会加载该路径。若文件不存在,点击 `Load Default` 会创建默认资产。
## FaceSdkSettings Fields
## 2. FaceSdkSettings 字段
| Field | Type | Description |
| 字段 | 类型 | 说明 |
|---|---|---|
| `TransportMode` | `FaceTransportMode` | `Auto`, `SerialPort`, or `Mock` |
| `UseMockInEditor` | `bool` | Force mock transport in Unity Editor |
| `PortName` | `string` | Runtime serial port |
| `BaudRate` | `int` | Runtime baud rate |
| `ReadBufferSize` | `int` | Runtime read buffer size |
| `UseEditorSerialDebugParameters` | `bool` | Use separate serial parameters in Editor |
| `EditorPortName` | `string` | Editor debug serial port |
| `EditorBaudRate` | `int` | Editor debug baud rate |
| `EditorReadBufferSize` | `int` | Editor debug read buffer size |
| `MockResponseDelayFrames` | `int` | Mock response delay in frames |
| `AutoVerifyOnOpen` | `bool` | Start auto verify after READY |
| `AutoVerifyTimeout` | `byte` | Auto verify protocol timeout in seconds |
| `AutoVerifyResultIntervalMs` | `int` | Minimum interval between auto verify result events |
| `StopAutoVerifyBeforeExclusiveCommand` | `bool` | Stop auto verify before exclusive commands |
| `ExclusiveCommandPolicy` | `FaceExclusiveCommandPolicy` | Policy when exclusive commands run during auto verify |
| `DebugLogEnabled` | `bool` | Enable SDK debug logs |
| `RawLogEnabled` | `bool` | Dispatch raw TX/RX logs |
| `LogPrefix` | `string` | Log prefix |
| `TransportMode` | `FaceTransportMode` | 通信模式:`Auto`、`SerialPort`、`Mock` |
| `UseMockInEditor` | `bool` | Editor 下是否强制使用 Mock |
| `PortName` | `string` | Player / 运行时串口号 |
| `BaudRate` | `int` | Player / 运行时波特率 |
| `ReadBufferSize` | `int` | Player / 运行时读取缓冲区 |
| `UseEditorSerialDebugParameters` | `bool` | Editor 下连接真实串口时是否使用单独参数 |
| `EditorPortName` | `string` | Editor 调试串口号 |
| `EditorBaudRate` | `int` | Editor 调试波特率 |
| `EditorReadBufferSize` | `int` | Editor 调试读取缓冲区 |
| `MockResponseDelayFrames` | `int` | Mock 响应延迟帧数 |
| `AutoVerifyOnOpen` | `bool` | READY 后是否自动开启验证 |
| `AutoVerifyTimeout` | `byte` | 自动验证协议超时时间,单位秒 |
| `AutoVerifyResultIntervalMs` | `int` | 自动验证结果最小派发间隔,0 表示不节流 |
| `StopAutoVerifyBeforeExclusiveCommand` | `bool` | 独占业务命令前是否自动关闭自动验证 |
| `ExclusiveCommandPolicy` | `FaceExclusiveCommandPolicy` | 自动验证开启时的独占命令处理策略 |
| `DebugLogEnabled` | `bool` | 是否启用 SDK Debug 日志 |
| `RawLogEnabled` | `bool` | 是否派发原始 TX / RX 日志 |
| `LogPrefix` | `string` | 日志前缀 |
## TransportMode
## 3. TransportMode 选择
| Mode | Behavior |
| 模式 | 行为 |
|---|---|
| `Auto` | Editor chooses mock or serial based on `UseMockInEditor`; Player uses serial |
| `SerialPort` | Use `SerialPortTransport` |
| `Mock` | Use `MockFaceModuleTransport` |
| `Auto` | Editor 根据 `UseMockInEditor` 选择 Mock 或串口;Player 使用串口 |
| `SerialPort` | 使用 `SerialPortTransport` |
| `Mock` | 使用 `MockFaceModuleTransport` |
When `UseMockInEditor = true`, the Editor uses mock transport and does not open a real serial port.
Editor 下有一个额外优先级:
## Auto Verify
```text
UseMockInEditor = true 时,强制使用 Mock,不打开真实串口。
```
`AutoVerifyTimeout` is sent to the SI-M1 module as the recognition timeout.
因此 Editor 中如果需要连接真实串口,必须将 `UseMockInEditor` 设为 `false`。
`AutoVerifyResultIntervalMs` is handled by the Unity SDK. It limits how frequently `OnAutoVerifyResult` is dispatched when the module sends continuous auto verify NOTE packets. Set it to `0` to dispatch every result.
## 4. Editor Serial Debug 参数
`StopAutoVerifyBeforeExclusiveCommand` and `ExclusiveCommandPolicy` control how enrollment, user management, QR code, image capture, and feature operations behave while auto verify is active.
Editor 连接真实硬件时,建议开启:
## Runtime Usage
```text
UseEditorSerialDebugParameters = true
```
开启后,Editor 中串口使用:
- `EditorPortName`
- `EditorBaudRate`
- `EditorReadBufferSize`
Player 中仍使用:
- `PortName`
- `BaudRate`
- `ReadBufferSize`
这样可以避免 Editor 调试口和发布运行口互相覆盖。
## 5. Editor 工具按钮
配置窗口按钮:
| 按钮 | 行为 |
|---|---|
| `Load Default` | 固定加载或创建默认路径的 `FaceSdkSettings.asset` |
| `Save` | 保存当前配置并同步场景中的 Manager |
| `Save and Create/Update Manager` | 保存配置后创建或更新场景 Manager |
同步 Manager 时会写入:
- `m_settings`
- `m_config.TransportMode`
- `m_config.UseMockInEditor`
- 串口参数
- Editor 串口参数
- Mock 延迟
- 自动验证配置
- Raw Log 开关
PlayMode 中同步配置时,会调用 `FaceModuleManager.ApplySettings(settings)`,立即重建当前 transport。
## 6. Manager 配置方式
推荐方式:
```csharp
manager.ApplySettings(settings);
manager.Open();
```
Quick configuration:
兼容方式:
```csharp
manager.Configure(useMockInEditor: true, portName: "COM3", baudRate: 115200);
manager.Open();
```
Custom transport:
外部通信层注入:
```csharp
manager.ConfigureTransport(customTransport);
manager.Open();
```
## 7. 场景约束
每个场景建议只保留一个 `FaceModuleManager`。
多个 Manager 可能导致:
- 多次打开同一串口。
- 重复接收和派发事件。
- UI 状态不一致。
`Create Manager GameObject` 菜单会校验 Manager 数量,并在存在多个 Manager 时停止创建。
## 8. 自动验证配置
`AutoVerifyTimeout` 是发送给模组的协议超时时间,不是结果间隔。
`AutoVerifyResultIntervalMs` 是 Unity SDK 侧的事件节流间隔。自动验证开启后,硬件可能持续通过 NOTE 上报识别结果,SDK 会按该间隔派发 `OnAutoVerifyResult`,避免 UI 或业务层被连续结果刷爆。
关闭连接时,`FaceModuleManager.Close()` 和 `CloseAsync()` 会先尝试关闭自动验证,再执行 `FaceResetAsync()`,最后关闭串口。`OnApplicationQuit()` 也会走同一套安全关闭流程,避免应用退出后硬件继续检测。
## 9. 独占命令策略
自动验证开启后,模组会持续进行检测。录入、删除、查询、照片注册等业务命令可能与自动验证互相冲突。`FaceExclusiveCommandPolicy` 用于控制 SDK 在执行这些命令前如何处理自动验证状态。
| 值 | 行为 | 适用场景 |
|---|---|---|
| `RejectWhenAutoVerifyEnabled` | 自动验证开启时直接拒绝独占命令 | 希望业务层显式控制状态切换 |
| `StopAutoVerify` | SDK 在独占命令前自动关闭自动验证 | 默认推荐,减少业务层重复处理 |
| `Ignore` | SDK 不处理自动验证状态 | 调试或自定义流程,业务层自行保证不冲突 |
## 10. 运行时状态码入口
配置项会影响以下运行时状态和返回值,详细枚举表见 `SDK_API_Reference.md`。
| 类型 | 使用位置 | 说明 |
|---|---|---|
| `FaceResultCode` | `ResultCode`、`OnError`、`FaceCommandException` | 命令和业务结果码 |
| `FaceStateCode` | `OnFaceStateUpdated` | 人脸位置、遮挡、闭眼等状态 |
| `FaceModuleStatus` | `CurrentStatus`、`GetStatusAsync()` | 模组待机、忙碌、错误状态 |
| `FaceTransportMode` | `FaceSdkSettings.TransportMode` | 通信模式 |
| `FaceExclusiveCommandPolicy` | `FaceSdkSettings.ExclusiveCommandPolicy` | 自动验证与独占命令冲突策略 |

Binary file not shown.

Binary file not shown.

View File

@ -1,7 +1,7 @@
{
"name": "xin.aisu.si-m1.face",
"displayName": "AISU SI-M1 Face SDK",
"version": "0.1.7",
"version": "0.1.8",
"unity": "2021.3",
"description": "Unity UPM package for the AISU SI-M1 face recognition module protocol, transport, command services, lifecycle manager, and demo samples.",
"author": {