Persona 會執行一個本機 WebSocket 伺服器,供其他應用程式驅動:切換場景、新增並擺放圖層、開關表情、播放動作、播放帶口型的語音、讀取追蹤狀態,以及直接寫入模型參數
它預設關閉。在 設定 → 外掛 API 中開啟,建立一把金鑰,再把權杖貼進你的外掛
開啟
| 控制項 | 作用 |
|---|---|
| 啟用 API | 啟動伺服器。沒有金鑰就連不上 |
| 連接埠 | 預設 25034 |
| 允許區域網路存取 | 綁定到本機回送位址之外,讓手機或另一台電腦也能連上 |
開啟區域網路存取後,Persona 會顯示本機對外回應的位址,讓你知道該把瀏覽器指向哪裡
如果連接埠已被佔用,這一節會直接顯示錯誤,而不是默默失敗
API 金鑰
金鑰是必要的——未經認證的連線會被拒絕。建立金鑰 會讓你為金鑰命名,並把它的權杖完整顯示一次;該列上的複製按鈕隨時可以再次取出完整權杖
| 動作 | 作用 |
|---|---|
| 複製權杖 | 把完整權杖複製到剪貼簿 |
| 重新命名金鑰 | 原地改名 |
| 撤銷金鑰 | 刪除它。正在使用它的工作階段會被關閉,並被告知不要重連 |
每個金鑰列還會顯示已連線、從未使用,或者以相對時間顯示最近使用於…。用戶端表明身分後,該列會記住最近一次的名稱與版本,因此沒有用戶端連線時也認得出這把金鑰
權杖保存在作業系統的安全儲存區裡。在沒有安全儲存區的電腦上,建立金鑰會失敗並給出說明,而不是把權杖寫進明文檔案
外掛資料夾
外掛可以請求 Persona 註冊一個模型或素材檔案,之後再載入它。這只對位於你在 外掛資料夾 中新增過的資料夾內的檔案有效——其他任何路徑都會以 forbidden-path 拒絕
已連線的用戶端
伺服器執行期間,每個開啟中的工作階段都會列出來,顯示它宣告的名稱、版本、開發者、用的是哪把金鑰,以及從哪裡連入。瀏覽器用戶端會顯示自己的頁面來源
從不表明身分的用戶端會列為 未識別的用戶端,功能完全一樣。該列上的中斷按鈕會關閉那個工作階段,並告訴它不要重連
每接受一次連線,還會跳一則靜音的系統通知,寫明是哪個用戶端、用的哪把金鑰、從哪裡連入——金鑰落到別人手裡,一被使用就會露出來。系統拒發通知時——沒簽章的開發版、權限被關掉——同一則訊息會在控制面板開啟期間以提示訊息的形式出現。它從不落到舞台上,那裡的東西會被擷取畫面帶走
把權杖當成密碼看待。它授予對應用程式的控制權,包括載入任何從你的外掛資料夾註冊的模型或素材。除非你開啟區域網路存取,伺服器只監聽本機回送位址
Web 控制台
persona-console.laplace.live 是基於這套 API 實作的瀏覽器控制台。作為第一方的「外掛」,你可以用它檢查連線,也可以在直播時透過手機或平板控制 Persona
填入主機、連接埠與金鑰後,就能控制場景、圖層、表情、動作、特效、相機、燈光、自動化、追蹤與設定。版面與桌面端的 控制面板 一致:左側是圖層清單,下方固定顯示舞台、追蹤、自動化與設定;寬度足夠時,選取項目的詳細內容會顯示在右側。每個部分都有獨立網址,可以加入書籤。選取模型後可調整它的表情、動作與參數綁定,選取場景效果下的特效後可調整其參數;選取的模型或 3D 物件還帶有自己的圖層效果。目前實例不支援的控制項會停用
圖層清單底部的新增到場景按鈕會開啟 素材庫,內容透過 API 從 Persona 的登錄表讀取。在控制台註冊檔案時,需要輸入檔案在桌面端電腦上的路徑,且檔案必須位於已設定的 外掛資料夾 內
場景素材 中,環境貼圖與 LUT 各有獨立的分頁。點選素材即可套用到目前場景,隨後會顯示確認提示。動畫沒有獨立分頁,因為 API 不支援直接播放動畫片段。請在全部分頁的類型選擇器中註冊動畫,再透過選擇…按鈕將其設為某個圖層的待機動畫
選取場景後,燈光分區會列出 3D 物件與環境自帶的 烘焙燈光,和桌面端一樣可以開關、調整強度。已載入素材的尺寸與 glTF 擴充資訊也在這裡顯示
金鑰可以未加密的形式儲存在瀏覽器中,也可以僅在本次工作階段中保留。控制請求直接傳送到本機或區域網路中的 Persona
從 HTTPS 託管版控制台使用未加密的 ws:// 連線時,請透過 127.0.0.1
連線到與瀏覽器同一台電腦上的 Persona。要連到另一台裝置上的實例,請用純 HTTP
提供控制台,或者在 Persona 前面加一層 TLS 代理並開啟 使用 TLS
(wss://)。首次連線還可能要求授予區域網路權限
沒有 API 介面的功能都留在桌面應用程式裡:更新程式、API 金鑰、系統匣圖示、視窗邊界、原生檔案選擇器、舞台控制點與快速鍵錄製。自動化 也只能在桌面端編輯:控制台的自動化頁會列出並執行它們,主模型的快速鍵則放在下方可摺疊的虛擬形象快速鍵區塊裡。在桌面端暫停的自動化會標為已暫停,無法執行
Stream Deck
Stream Deck 外掛 是同一套 API 的另一個第一方用戶端,把切換模型與場景、觸發快速鍵、表情與動作,以及移動、縮放形象放到實體按鍵上
MCP 伺服器
@laplace.live/persona-mcp 是第三個:一個 Model Context Protocol 伺服器,把這套 API 交給 AI 助理——Claude、Cursor、Codex——封成二十來個按任務劃分的工具,其餘的走 call_api,還有 stage.capture 讓助理看得見自己改出來的結果
SDK
@laplace.live/persona-sdk 是配套的具型別用戶端——在 Node、Bun、瀏覽器與 OBS 瀏覽器來源之間同構
import { PersonaClient } from "@laplace.live/persona-sdk";
const persona = new PersonaClient({ token: "sk-lp-v1-…" });
await persona.connect();
await persona.call("expression.toggle", { name: "Smile" });
persona.on("motion.started", (m) => console.log("playing", m.group));每個方法都由同一份共享的型別表描述,因此一次呼叫的請求與回應形狀由方法名稱決定。SDK 參考 涵蓋安裝、用戶端選項、認證、參數租約與每一個匯出的型別
事件
工作階段只會收到已訂閱的事件。SDK 會在重新連線後自動恢復訂閱
| 事件 | 觸發時機 |
|---|---|
scene.changed | 任何場景變更:建立、刪除、重新命名、啟用或編輯 |
scene.loading | 場景套用或渲染管線預熱的開始與結束 |
settings.changed | 應用程式設定變更 |
instance.loaded | 一個模型實例在舞台上載入完成 |
selection.changed | 編輯選取項變動,來源不限 |
expression.changed | 目前生效的表情組合變更 |
expression.persistence | 某個模型的「記住表情」開關被切換 |
motion.started | 一段動作開始播放;帶 motion-stop 的主機還會附上 oneShot |
motion.ended | 一段動作播放結束 |
speech.started | 一段 speech.play 的語音開始播放 |
speech.ended | 該段語音結束——播完、被停止或被頂替都算 |
hotkey.state | 快速鍵設定變更 |
automation.state | 自動化的清單、名稱、觸發條件種類、啟用狀態或系統註冊狀態發生變化 |
tracking.status | 臉部或姿勢追蹤狀態變更,或任一來源自身的狀態變更——包括攝影機的臉部、手部與身體追蹤 |
registry.changed | 有模型或素材被註冊——需要重新讀取對應的清單 |
方法一覽
以模型為作用域的方法接受可選的 instanceId,預設作用於場景的 主模型
| 分組 | 方法 |
|---|---|
scene.* | list get activate create duplicate rename delete patch inspect setLightFollowCamera |
instance.* | list get add setModel remove setVisible setEffects setTrackingSources reorder setPrimary setPlacement attach setMToon setIdle setControllerMovement setLipSync info |
binding.* | get preview set release inputs override |
controller.* | state rename setDeadZone remove assign |
selection.* | get set |
object.* | add addMany rename setContent setSpace setPlacement attach setLightOverrides anchors |
expression.* | list active toggle getPersistence setPersistence |
motion.* | list play playing stop |
speech.* | play stop |
hotkey.* | list set trigger |
automation.* | list run |
model.* / asset.* | 各自的 list 與 register,外加 registry.thumbnail |
settings.* | get patch |
tracking.* / pose.* | tracking.addSource tracking.updateSource tracking.removeSource、setEnabled、setSource,外加 pose.setPort 與 tracking.status |
lipSync.* | state configure restart calibrate |
stage.* | resetTransform resetCamera spawn clearSpawned capture |
app.* / session.* | app.info app.localAddresses app.stats,以及 session.identify |
storage.* | get set delete list |
param.* | inject release |
scene.create 追加一個空場景並啟用它,和在應用程式裡新建一個場景一樣,所以回傳裡的 activeSceneId 就是新場景——新場景的 id 從這裡讀,而不是去比對前後兩份場景清單,因為中間可能夾進別的工作階段建立的場景
scene.patch 編輯目前場景的背景、相機、燈光、環境與 轉場;場景項目則透過 instance.* 與 object.* 修改。enabled 為 false 的燈光會連同陰影一起熄滅,其餘設定都會保留。該欄位預設為 true,不支援關閉燈光的建置不會帶這個欄位
vrmCamera 整體取代:orbit、fov(1 – 179°)、roll(繞視線軸旋轉的弧度)、projection(perspective 或 orthographic)與 clipAssetId。舊版建置不帶 roll 與 projection——視為 0 與 perspective——所以提供這兩項控制項之前,先看回傳的相機裡有沒有。環繞的角度可以取任意弧度,distance 也可以是負數,滑鼠導覽則保留自己較窄的範圍。正交視圖的寬度是 abs(distance),fov 保留但不起作用,distance 為負時兩個軸都會翻轉。stage.resetCamera 也會重設滾轉與投影
object.add 可以帶 place2d 或 place3d,物件在同一次編輯裡就落在該位置,不會先在預設位置畫出一個影格;取值依 object.setPlacement 的規則修正。object.addMany { objects } 把最多 100 筆同樣的項目作為一次場景編輯加入——只儲存一次,復原也只算一步——並依請求順序回傳 instanceIds。只要有一個素材無法解析,就一個也不加入
instance.attach { instanceId, attach } 把一個 Live2D 實例作為 物品 釘選到另一個 Live2D 模型上,attach 與 object.attach 的相同;傳 null 則原地解除。attach.depth 取 { kind: 'front' }、{ kind: 'behind' } 或 { kind: 'artMesh', id },最後一種把物品插在父模型那個 ArtMesh 的正上方——父模型沒有的 ID 視為前方。attach.split 即 { itemArtMesh, depth },在物品自己的某個 ArtMesh 處切開,把它下面的部分送到第二個深度。object.anchors 的每一列帶有 order,即取得清單時該 ArtMesh 的繪製順序,深度控制項就是依它排列各格的。會形成循環的釘選回傳 invalid-params,對 VRM 實例呼叫則回傳 unsupported-for-format。對物件而言,目前只有 front 生效
stage.capture 需要 stage-capture 能力,回傳 { dataUrl, width, height }:舞台視窗此刻顯示的樣子,一張帶透明通道的 PNG,最長邊縮到不超過 maxEdge(64 – 2048,預設 1024),且從不放大。看不見螢幕的用戶端——比如經由 MCP 伺服器 的 AI 助理——就是靠它確認自己的改動。每擷取一張,算繪都要停下一幀,所以按需取用,不要輪詢。renderer-unavailable 表示當時沒有舞台視窗,或者沒有可複製的影格;舞台當掉後直到重新載入畫出第一幀為止都會回傳它,所以該重試而不是放棄
能力
應用程式層級與實例層級的能力清單說明目前版本支援哪些功能。請以能力清單為準,不要透過比較版本號碼來判斷
應用程式層級的那份由 hello 與 app.info 回報——目前是 storage、speech、automations、layer-effects、scene-transitions、area-lights、spot-lights、camera-follow-lights、shadow-filters、environment-map-model、spawn、tracking-lost、motion-stop、stage-capture、controllers、model-editing 與 asset-inspection。每個實例自己的那份在 instance.list 的 capabilities 裡,能力表涵蓋不到的方法會以 unsupported-for-format 拒絕
後三項各自開啟一批共享編輯器的方法:controllers 是 controller.*(讀取已連接的裝置與已儲存的設定檔,改名、設死區、移除、發起指派),以及用 settings.patch 寫 controller.enabled 這個總開關——裝置指的是接在桌面端上的,不是瀏覽器所在那台電腦上的;model-editing 是 binding.*(讀取、預覽、寫回與釋放某個模型的參數綁定,並做短時的輸入覆寫)連同 instance.setBreath,其中 binding.inputs 回傳 { inputs, outputs }:inputs 是即時的追蹤輸入,outputs 依輸出 id 給出每個被綁定的參數此刻在模型上的讀數——已經算完動作、表情與物理演算之後的值,讀不回來的輸出不列出;asset-inspection 是 scene.inspect 與 registry.thumbnail
instance.setControllerMovement 合併某個實例的 控制器移動 設定:enabled、slot(已儲存的設定檔編號)、moveSpeed、turnSpeed、smoothing,VRM 上還有 walkEnabled、walkClip、walkSpeed 與 faceMovement。越界的值會被修正到預設值或邊界上;對物件呼叫會傳回 unsupported-for-format。walkClip 接受和 instance.setIdle 一樣的引用
動作與待機
motion.list 列出模型的動作群組。Live2D 模型還會把模型資料夾裡每一個 .model3.json 沒有宣告的 .motion3.json 一併列出,各自成為一個以檔案名稱命名的群組——在桌面端動作分區裡 錄下來的動作 因此無需重新載入就會出現
motion.stop(應用程式能力 motion-stop)把正在播放的動作淡出,讓待機接回去。只有待機在播時它什麼都不做,回傳 { stopped: false }。motion.playing 的 oneShot(motion.started 上也有)說明回報的這段動作是不是蓋在待機之上的那一種,也就是 stop 會結束的那一種;舊版建置不帶這個欄位
instance.setIdle 合併某個實例的待機設定:
| 欄位 | 說明 |
|---|---|
idleAnimation | 待機總開關。false 會停下 VRM 的片段,Live2D 上則停下每一段待機動作,包括模型自己的 Idle 群組 |
idleClip | 僅 VRM。待機片段的參照 |
idleMotion | 僅 Live2D,需實例能力 idle-motions。motion.list 裡的一個動作檔案,在其他所有動作之下循環;null 表示隨機播放模型的 Idle 群組。模型不再列出的檔案按 null 處理 |
trackingLostBehavior | 需 tracking-lost。hold 保持最後追蹤到的姿態,idle 用約 0.3 秒回到待機、臉回來時再回去 |
trackingLostMotion | 需 tracking-lost,僅 Live2D。臉消失夠久之後頂替待機的那個動作,null 表示不換 |
trackingLostDelay | 需 tracking-lost。「夠久」是多少秒,0 – 60 |
instance.get 會把這幾項一併回報
燈光
帶 area-lights 能力的建置接受類型為 area 的 SceneLight:一塊位於 x/y/z 的矩形,以 azimuth/elevation(度)指向,以 roll(−180 – 180°,預設 0)在自身平面內旋轉,尺寸由 width 與 height 決定(各 0.01 – 20 場景單位,預設 1)。它照亮 PBR 材質與 MToon 虛擬形象——MToon 在自己的卡通著色裡用四個光照取樣來近似這塊矩形——但不影響 Live2D,也不投射陰影。它的 range 與陰影設定會保留,以便之後切換類型
帶 spot-lights 能力的建置接受類型 spot,它使用 x/y/z、azimuth/elevation 與 range(0.1 – 20 場景單位)。方位角與仰角都為 0 時光束指向 −Z,仰角為正時朝下。angle 是光錐的半角(1 – 89°,預設 30),penumbra 柔化光錐邊緣(0 – 1,預設 0.3)。強度範圍 0 – 20,與點光源相同。聚光燈照亮 PBR 與 MToon 材質,支援一般的陰影等級與半徑,也能點亮體積光照的霧氣。面光源與聚光燈——無論是新增還是切換類型——只在帶對應能力的建置上提供
shadowFilter 為每盞平行光、點光源或聚光燈單獨選擇 pcf(預設)或 pcss,兩者可以在同一個場景裡並存。shadowQuality 仍然決定貼圖解析度,off 仍然關閉投射。PCF 依 shadowRadius(陰影貼圖紋素)柔化。PCSS 會搜尋遮擋物,陰影離投射物越遠,半影越寬,寬度取決於 shadowSourceSize:光源直徑,平行光以度計,點光源與聚光燈以公尺計(0 – 10,預設 0.1),為 0 時是硬光源。PCSS 不會改動已儲存的 shadowRadius,舊場景載入後是 PCF。過濾方式的選擇要依 shadow-filters 能力判斷——本機新增的燈即使在不支援的建置上也可能帶著 shadowFilter
帶 camera-follow-lights 能力的建置接受燈光上的 followCamera,環境光會忽略它。它預設是 false;為 true 時,x/y/z 與各個角度都相對相機計算,於是燈光會隨手動編輯相機、也隨相機運動播放一起移動。followCameraOptions 選擇跟隨哪些部分,各項預設 true:position 跟隨相機的注視目標與平移,rotation 跟隨它在世界空間中含滾轉在內的旋轉,distance 跟隨帶正負號的環繞距離。只改 fov 永遠不會移動燈光。關掉的部分改用 followCameraReference——targetX、targetY、targetZ、distance 與世界空間的 rotation 四元數——即關掉那一刻定格的值;缺少參考時依目標為零、單位旋轉、距離為零處理
scene.setLightFollowCamera { lightId, followCamera, options? } 為目前場景的一盞燈切換跟隨,或把 options 合併進它的選擇,同時不移動它、也不改變它的朝向:桌面端依畫面上的相機(包括正在播放的相機運動)換算這盞燈的座標,回傳換算後的 { light },燈已不存在時為 light: null。scene.patch 與已儲存的場景則依寫入的值原樣使用,不做這種換算。這些欄位與這個方法都要依 camera-follow-lights 判斷
SceneLight.volumetric 為單盞點光源、聚光燈或面光源開啟受光照亮的霧氣。它預設是 false,其他類型會忽略它。舊版建置不帶這個欄位,而是整個場景共用一個開關,所以提供這項控制項之前先檢查欄位是否存在;開啟那個開關儲存的場景,載入後每盞能點亮霧氣的燈都會開啟 volumetric
SceneEnvironment 新增了兩個可選欄位 volumetricLighting 與 clusteredLighting。舊版建置不帶它們,所以提供這兩項控制項之前先檢查欄位是否存在。volumetricLighting 決定整個場景裡霧氣的樣子,本身沒有開關——沒有哪盞亮著的燈開啟霧氣時,就沒有霧氣。目前的版本會回傳完整的霧氣設定,並把 clusteredLighting 修正為關閉;修改它們走 scene.patch 的環境
volumetricLighting 欄位 | 取值 | 預設值 |
|---|---|---|
density | 0 – 10 | 1 |
intensity | 0 – 10 | 1 |
range | 距相機 1 – 100 場景單位 | 20 |
quality | low、medium、high | medium |
speed | 0 – 5;為 0 時霧氣靜止 | 0.2 |
霧氣圍繞開啟了它的燈發光,會被深度遮擋,未被照亮處保持透明;只要有一盞亮著的場景光源開啟了它,3D 物件與環境模型自帶的點光源、聚光燈與面光源也會加入。它需要透視相機:正交投影下設定保留,但不渲染霧氣。平行光與環境光不參與,Live2D 也不會遮擋它。clusteredLighting: true 會在 WebGPU 透視相機下,為 1 – 64 盞範圍有限、不投射陰影的點光源加速表面光照。有點光源沒有範圍上限、數量超出,或渲染器、相機不受支援時,照舊使用一般光照。它不會降低陰影的渲染開銷,也不會改變霧氣所用的光源
帶 environment-map-model 能力的建置上,SceneEnvironment 可以同時帶 iblAssetId 與 modelAssetId。此時 bakeFromModel 選擇從模型產生光照,貼圖作為它的輸入;為 false 時直接用貼圖照明,沒有貼圖時退回模型自帶的天空。showSkybox 只管顯示,無論由誰照明,畫的都是貼圖或那片天空。清除其中一項會保留另一項,SDK 的 environmentClearPatch() 可以產生這種修改。舊版建置同一時間只能有一項環境素材,在那裡設定其中一項時要清掉另一項
還有三個可選欄位透過 scene.patch 調整全景圖:skyboxBlur(0 – 1,預設 0)與 skyboxIntensity(0 – 2,預設 1)只影響看得見的天空盒,iblRotation(弧度,預設 0,可以超過一整圈)讓全景圖與它的光照一起轉動,模型產生光照所用的天空也一樣。舊版建置不帶這些欄位,所以欄位存在時才提供對應控制項
物理模擬
SceneEnvironment.physics 就是場景的 物理模擬 開關:3D 物件會落到舞台地面上,也會落在 VRM 虛擬形象身上。它預設是 false,舊版建置不帶這個欄位。模擬出的姿態從不儲存,讀回的物件擺放始終是寫入的值,把 physics 關掉,每個物件都會回到原位
帶 spawn 能力的建置還接受 stage.spawn,它把已註冊的 prop 素材複製成一批受物理驅動的物體,投放到舞台上。這些副本只存在於渲染器裡——沒有場景項目,沒有圖層列,不能復原,也不會儲存——同一個檔案的所有副本共用幾何體、紋理與繪製呼叫,所以數量上百也依然輕量。目前場景的 physics 關閉時,呼叫回傳 invalid-state;素材不是已註冊的 prop 時回傳 not-found;否則回傳 { spawned, alive },其中 alive 統計所有素材的物體
| 欄位 | 意義 |
|---|---|
assetId | 已註冊的 prop 素材 |
count | 1 – 200,預設 1。舞台上的物體超過 500 個時,最早的會讓出位置 |
origin | 散佈立方體的中心,{ x, y, z },以公尺為單位。預設 { x: 0, y: 3, z: 0 },在虛擬形象站立處的上方 |
spread | 散佈立方體的邊長,0 – 20 公尺,預設 1 |
velocity | 所有物體共用的初速度,{ x, y, z },以公尺每秒為單位,每個軸在 ±50 以內。預設靜止 |
scale | 0.01 – 100,預設 1 |
ttlMs | 每個物體存在多久,0 – 600000 毫秒,預設 30000。0 表示一直保留到被清除 |
transition | { style, inMs, outMs }:只為這批物體另選 顯示與隱藏 樣式,出現與消失各用 0 – 5000 毫秒。省略的欄位沿用場景的設定 |
超出範圍的數值會被修正到邊界上。物體會在 ttlMs 到期、切換到其他場景或關閉 physics 時離開,也可以用 stage.clearSpawned {} 清除——它回傳 { cleared },還會取消仍在載入素材的投放
場景轉場
scene.activate 會等目標場景載入完成並接管舞台——這段期間原場景照常運作、可以編輯——但不會等轉場把它完全揭開。較新的切換會頂替尚未完成的那次,所以回應裡回報的是實際生效的場景,不一定是你請求的那個。SDK 給切換場景保留 120 秒,設定了 requestTimeoutMs 時以它為準
帶 scene-transitions 能力的建置會在 Scene.transition 裡帶上每個場景的 轉場,也就是進入該場景時播放的效果。scene.patch { transition } 會整個取代它,但不會播放:
| 欄位 | 意義 |
|---|---|
type | cut、fade、wipe、circle、image 或 video |
durationMs | 100 – 10000 毫秒 |
color | 淡入、擦除或圓形展開的遮罩顏色,十六進位 |
assetId | 已註冊的圖片或影片,或 null |
switchPoint | 影片中切換場景的位置,0.05 – 0.95。請選一個完全蓋住舞台的影格 |
autoFade | 讓影片淡入淡出。預設關閉 |
fadeInMs / fadeOutMs | 各為 0 – 10000 毫秒的播放時間,預設 300,分別以切換點之前與之後的時間為上限。0 關閉該淡變 |
所有切換場景的方式都使用目標場景的轉場。除了直接切換,轉場都會立即開始,並一直遮住舞台直到目標場景就緒,載入較慢時會超出 durationMs 自動延長。影片靜音播放,速度隨時長調整,等待期間停在切換影格上
顯示與隱藏
SceneEnvironment.itemTransition { style, durationMs } 就是場景的 顯示與隱藏 設定:場景裡的模型、物件與生成物體如何出現與消失。舊版建置不帶這個欄位。style 是 glitch(帶撕裂與灼燒的抖動溶解,預設)、dither(不帶額外效果的抖動溶解)、pop(縮放出現與消失)或 cut,durationMs 取值 0 – 5000,預設 300。cut 無論 durationMs 是多少都不會漸變,0 也等同於 cut。修改它走 scene.patch 的環境
圖層特效
帶 layer-effects 能力的建置允許單個模型或物件帶上自己的 特效,在它併入場景之前生效。每個場景項目都有自己的 effects 與 effectLayers,結構與場景的一致,由 instance.setEffects { instanceId, effects, effectLayers? } 編輯:
effects接受color、levels、colorWheels、colorShift、selectColors、gradient、blur、bloom、diffusion、rim、outline與dropShadow的部分設定,沒寫到的保持原值effectLayers傳入時會取代已新增特效的清單。已啟用的特效始終在清單裡
回應是修正後的結果:數值被限制在範圍內,未知的鍵被捨棄。格式有誤的特效會讓整個呼叫在任何變更生效之前失敗
圖層特效作用於模型和位於 3D 空間的物件。2D 物件會回傳 unsupported-for-format;它們已儲存的設定會保留,等空間改變後再生效
追蹤來源
Persona 可以同時執行多個已設定的追蹤來源。settings.tracking.sources 列出它們,tracking.addSource、tracking.updateSource 與 tracking.removeSource 管理這份清單。instance.setTrackingSources 依來源 id 將實例的臉部、姿勢與手部通道(faceSourceId、poseSourceId、handSourceId)綁定到對應來源。設為 null 會停止該通道的追蹤,不存在的 id 也視同 null。新實例預設綁定各通道的預設來源;同一個來源可以同時驅動多個實例
instance.setTrackingSources 還接受 handTrackingMode:arms 讓追蹤到的手同時帶動 VRM 的手臂、手腕與手指,fingers 只動手指,手臂留給 VMC 或 mocopi 的身體追蹤
臉部追蹤來源可以是 persona-ios、ifacialmocap 或 vts-ios,也可以用選填的 phoneIp 固定一部傳送裝置。姿勢追蹤來源使用 vmc 或 mocopi。port 屬於 vmc、mocopi 和 ifacialmocap——若該連接埠已被其他來源佔用,請求會被拒絕,只有幾個 ifacialmocap 來源之間共用一個 socket;persona-ios 與 vts-ios 的連接埠由協定本身固定。已淘汰的 vts-ios-native 會在協定層被拒絕
mediapipe 是 攝影機 追蹤來源,最多只能有一個,沒有 port 或 phoneIp。它的 mediapipe 選項開關三項任務——face、hands、body,分別對應三個通道——並設定 deviceId('' 表示預設攝影機)、mirror 與 delegate(CPU 或 GPU)。預設開啟鏡像、在 CPU 上執行,追蹤臉部與手部而不追蹤身體。tracking.addSource 與 tracking.updateSource 接受部分選項,沒寫到的保持原樣。追蹤到的手還會驅動 注入 一節列出的手部輸入
tracking.status 回傳網路臉部來源與姿勢來源的彙總狀態,以及 sources 對應表中每個已設定來源的獨立狀態,攝影機也在其中;tracking.status 事件帶有相同的結構,只有單一來源的狀態變更時也會觸發
舊的單一來源方法仍然作用於對應通道的第一個網路來源:tracking.setSource 修改其種類,pose.setSource 在需要時建立 VMC 來源並回傳它的連接埠,pose.setPort 則修改該連接埠。tracking.setEnabled 與 pose.setEnabled 仍是網路臉部來源與姿勢來源的總開關。攝影機只聽它自己的 enabled,透過 tracking.updateSource 設定,任務選擇與模型指派都會保留
麥克風口型同步
口型同步 用桌面端的麥克風驅動口型。麥克風與輸入裝置清單都是桌面端的,不是瀏覽器所在那台電腦上的;音訊與校正資料都不會經過 API。分析結果還會驅動 注入 一節列出的聲音輸入
| 方法 | 作用 |
|---|---|
lipSync.state | 讀取設定、擷取狀態(off、starting、listening 或 error)、桌面端的輸入裝置、即時音量與母音取樣,以及進行中的校正 |
lipSync.configure | 合併一份部分設定——enabled、deviceId、gain(0 – 30 dB)、noiseGate(−60 – 0 dBFS)、smoothing(0 – 0.3 秒)——並回傳儲存後的結果 |
lipSync.restart | 在下一個影格重新啟動擷取。它既不會開啟已關閉的麥克風,也不會等擷取完成,請輪詢 lipSync.state |
lipSync.calibrate | 執行一步校正並回傳新狀態 |
同一份設定也以 settings.lipSync 出現,settings.patch 同樣接受。校正使用桌面端選取的麥克風,並與桌面面板共用:start 開始一份草稿,record 搭配 phoneme(A、I、U、E、O,或代表背景噪音的 S)把該聲音錄兩秒,六個都錄完後用 preview 套用草稿,最後 save 或 cancel 結束。reset 讓目前的麥克風回到內建設定檔。錄製會立即回傳,進度請輪詢 lipSync.state:其中的 calibration 會回報目前階段 phase(ready、recording 或 verifying)、正在錄製的聲音與已錄完的聲音。不符合目前階段的步驟會得到 invalid-state
instance.setLipSync { instanceId?, mode } 設定麥克風是否驅動某個模型:always(預設)、when-untracked(僅在它的臉部沒被追蹤時)或 off。對物件呼叫會回傳 unsupported-for-format
語音
speech.play 播放一段音訊,並用它的響度驅動口型。它只作用於能力表裡帶 speech 的實例——目前是已載入的 Live2D 模型。判斷依據始終是實例的執行階段能力而不是格式:0.53 及更早的版本在已移除的舊版 WebGL 引擎下不回報它
| 參數 | 說明 |
|---|---|
url | https:、http:(本機 TTS 橋接)或內嵌的 data:audio/* 負載 |
volume | 選填,0..1 |
instanceId | 選填,預設場景的主模型 |
一個模型同一時刻只有一段語音,新的播放會頂替正在播的那段。呼叫回傳即表示播放已經開始,沒能開始則是 invalid-state。speech.started 與 speech.ended 成對包住這段語音,speech.stop 提前結束它
自動化
帶 automations 能力的建置可以列出並執行應用程式的 自動化——由快速鍵、事件或請求觸發的一串舞台改動
| 方法 | 作用 |
|---|---|
automation.list | 列出全部自動化 |
automation.run | 依 id 執行其中一條 |
操作內容、觸發條件設定與編輯都留在應用程式一側。清單裡給出的是 id、title、accelerator、registered、enabled,以及 actionKinds 與 triggerKinds 兩份陣列——足夠畫出一列按鈕,不必知道每條操作具體做什麼。title 為 null 時用 actionKinds 拼一個標籤出來,SDK 的 automationLabel 做的就是這件事。actionSceneIds 與 actionKinds 一一對應,記錄每個 switch-scene 的目標場景(其他種類為 null),標籤因此可以寫出場景名稱——不過那個場景可能已經被刪除了
每條自動化都是一條時間軸,它的時間和其他內容一樣留在桌面應用程式裡,所以 actionKinds 的順序並不代表執行的先後。操作種類包括在時間軸開始前作為準備步驟執行的 switch-scene 與 load-model;暫時效果 effect-clip;play-camera-motion 與 stop-camera-motion;play-audio 與 audio-control;以及作用於虛擬形象的 toggle-expression、play-motion、remove-all-expressions、load-model 與 model-position。delay 已經移除——時間軸上的空白就是等待。音訊沒有自己的方法:檔案、播放與輸出裝置都留在桌面端,用戶端要播放聲音,就執行一條自動化。triggerKinds 列出這條自動化在快速鍵之外還有哪些種類的事件觸發條件——目前有 scene、model-loaded、motion、face-tracking、microphone 與 parameter
沒有指派鍵盤或控制器快速鍵時 accelerator 為 null——automation.run 照樣能執行它。暫停的自動化 enabled 為 false,會忽略所有觸發,包括 automation.run。automation.run 在派送後立即回傳,不等操作執行完。清單、名稱、觸發條件種類、啟用狀態或系統註冊狀態一有變化,automation.state 就會送來完整的新清單
actionKinds 與 triggerKinds 都是開放的:新版本可能送來這份 SDK
還不認識的種類。當成未知項處理,別當成錯誤——automationActionLabel
會把未知的操作歸到一個通用名稱下
外掛儲存空間
storage.* 為外掛提供持久化鍵值儲存空間,按 API 金鑰劃分命名空間。使用同一把金鑰的所有工作階段共用資料,撤銷金鑰也會刪除對應資料。值可以是任意 JSON
| 方法 | 作用 |
|---|---|
storage.get | 讀一個鍵。從沒寫過的鍵回傳 value: null |
storage.set | 寫一個鍵 |
storage.delete | 刪一個鍵。鍵本來就不存在也算成功 |
storage.list | 列出所有鍵,已排序 |
上限是鍵名 128 個字元、單一值序列化後 64 KB、每把金鑰 256 個鍵。會突破鍵數上限的 storage.set 得到的是 invalid-state
錯誤
persona.call 會擲出帶字串 code 的 PersonaApiError:
| 代碼 | 意義 |
|---|---|
parse-error | 這個訊框不是合法的 JSON |
invalid-request | 訊息封裝格式有誤 |
unknown-method | 這個建置沒有這個方法 |
invalid-params | 參數未通過驗證 |
not-found | 引用的 id 找不到對應物件 |
unsupported-for-format | 該實例的格式做不到這件事——例如對 Live2D 模型設定 MToon |
conflict | 參數租約被另一個工作階段持有 |
renderer-unavailable | 舞台無法回應——沒有視窗,或渲染行程正在重新載入 |
forbidden-path | 路徑不在任何已設定的外掛資料夾內 |
invalid-state | 目前不允許,例如刪除最後一個場景、儲存超額、音訊沒能開始 |
internal | 其餘所有情況 |
這套代碼是協定的一部分:用戶端會丟棄帶未知代碼的錯誤訊框,所以新增代碼只隨協定版本一起到來,新出現的失敗沿用現有這些
連線中斷
用戶端會在連線意外中斷後自動重新連線。以下關閉碼會停止自動重新連線,以遵循金鑰撤銷或使用者手動中斷連線的操作:
| 代碼 | 常數 | 原因 |
|---|---|---|
4001 | CLOSE_KEY_REVOKED | 金鑰已被撤銷 |
4002 | CLOSE_FORCE_DISCONNECTED | 使用者中斷了該工作階段 |
兩者都會讓用戶端最終停在 closed 狀態。傳入了 onClose 時,終止性關閉會交給它,並略過 onWarning;沒有 onClose 時則回退到 onWarning。1001 不在此列——它表示伺服器正在停止,等它回來重連即可
撤銷金鑰會立即捨棄待傳送的訊框,並以 4001 關閉使用該金鑰的連線。仍在等待舞台回應的請求不會繼續寫入。已傳送給舞台的操作可能完成,但其回應會被捨棄
版本不一致
協定自帶版本號,與所連接的建置不符時 SDK 會發出警告。訂閱一個舊版 Persona 不認識的事件並非致命錯誤——SDK 會退回到逐個訂閱,保留能用的,並逐一報出其餘事件的名稱
目前的協定版本是 4。此前的每次升級都從協定中移除了一些內容,所以針對舊協定撰寫的用戶端或外掛需要更新:
| 協定 | 變化 |
|---|---|
| 2 | Scene.behavior(視線跟隨游標)已移除,場景資料與 scene.patch 裡都沒有了 |
| 3 | stage.shockwave 已移除,呼叫它會得到 unknown-method |
| 4 | shortcut.list、shortcut.trigger 與 shortcut.state 改為 automation.list、automation.run 與 automation.state;shortcuts 能力改名為 automations,負載裡改用 automationId 與 automations |
最後更新於 2026年9月20日