00:00 / 00:00

Persona

プラグインAPI

Personaは他のアプリから操作できるローカルWebSocketサーバーを提供します。シーンの切り替え、レイヤーの追加と配置、表情の切り替え、モーションの再生、リップシンク付き音声の再生、トラッキング状態の取得、そしてモデルパラメータへの直接書き込みができます

既定ではオフです。設定 → プラグインAPIでオンにし、キーを作成して、そのトークンをプラグインに貼り付けてください

有効にする

コントロール効果
APIを有効にするサーバーを起動する。キーがなければ何も接続できない
ポート既定は25034
ローカルネットワークからのアクセスを許可ループバックを越えてバインドし、スマートフォンや別のマシンから接続できるようにする

ローカルネットワークからのアクセスをオンにすると、ブラウザからの接続に使えるアドレスが表示されます

ポートがすでに使われている場合、エラーが表示されます

APIキー

キーは必須です——認証のない接続は拒否されます。キーを作成でキーに名前を付けると、そのトークンが一度だけ全文表示されます。行にあるコピーボタンを押せば、いつでも全文を取り出せます

操作効果
トークンをコピー完全なトークンをクリップボードにコピーする
キーの名前を変更その場で名前を変更する
キーを失効させる削除する。そのキーを使っているセッションは閉じられ、再接続しないよう伝えられる

各キーの行には接続中未使用、または最終使用とその相対時刻が表示されます。クライアントが名乗ると、直近の名前とバージョンがその行に記録されるため、接続中のクライアントがいなくてもキーを見分けられます

トークンはOSの安全なストレージに保管されます。それが利用できないマシンでは、トークンを平文のファイルに書き込むのではなく、説明を添えてキーの作成が失敗します

プラグインフォルダ

プラグインはモデルやアセットのファイルを登録するようPersonaに依頼し、そのうえで読み込ませることができます。登録できるのはプラグインフォルダに追加したフォルダ内のファイルだけです——それ以外のパスはすべてforbidden-pathで拒否されます

接続中のクライアント

サーバーの動作中は、開いているセッションがすべて一覧表示されます。クライアントが申告した名前、バージョン、開発元、使用しているキー、そして接続元が表示されます。ブラウザのクライアントはページのオリジンを表示します

一度も名乗らないクライアントは不明なクライアントとして並びますが、機能はまったく同じです。行にある切断ボタンを押すとそのセッションが閉じられ、再接続しないよう伝えられます

接続を受け付けるたびに、どのクライアントがどのキーでどこから接続したかを示す無音のシステム通知も表示されます——キーが他人の手に渡っても、使われた時点で表に出ます。OSが通知を拒否する場合——署名のない開発ビルド、権限がオフ——は、同じ内容がコントロールパネルの表示中にトーストとして現れます。ステージには決して出ません。そこに出たものはキャプチャに写り込むからです

Webコンソール

persona-console.laplace.liveは、このAPIの上に実装されたWebコンソールです。公式の「プラグイン」として、接続の確認や、配信中にスマートフォンやタブレットからPersonaを操作する際に使えます

ホスト、ポート、キーを入力すると、シーン、レイヤー、表情、モーション、エフェクト、カメラ、ライティング、オートメーション、トラッキング、設定を操作できます。デスクトップのコントロールパネルと同じく、左側にレイヤー一覧、その下にステージトラッキングオートメーション設定が並びます。幅に余裕があれば、選択した項目の詳細が右側に表示されます。各セクションにはブックマークできるURLがあります。表情とモーション、パラメータのバインドはモデルを選択して操作し、エフェクトはシーンエフェクトから選んでパラメータを調整します。選択したモデルや3Dオブジェクトには、それぞれ独自のレイヤーエフェクトもあります。選択中のインスタンスが対応していない項目は無効になります

レイヤー一覧の下にあるシーンに追加ボタンからインベントリを開けます。内容はAPI経由でPersonaのレジストリから取得します。コンソールからファイルを登録する場合は、デスクトップ側のマシン上のパスを入力してください。プラグインフォルダに設定したフォルダ内のファイルのみ登録できます

シーンのアセットには、環境マップLUTのタブがあります。行をクリックすると現在のシーンに適用され、確認のトーストが表示されます。APIはクリップの直接再生に対応していないため、アニメーション専用のタブはありません。すべてタブで種類を選んで登録し、選択…ボタンからレイヤーの待機アニメーションに設定してください

シーンを選択すると、ライティングに3Dオブジェクトや環境に組み込まれたライトが並び、デスクトップと同じスイッチと強度スライダーで調整できます。読み込んだアセットのサイズやglTF拡張の情報もここに表示されます

キーは暗号化せずにブラウザへ保存するか、現在のセッション中だけ保持するかを選べます。操作リクエストは、手元のマシンまたはローカルネットワーク上のPersonaへ直接送信されます

APIのないものはデスクトップアプリ側に残ります。アップデーター、APIキー、トレイアイコン、ウィンドウの位置とサイズ、ネイティブのファイル選択、ステージ上のハンドル、ショートカットの記録です。オートメーションの編集もデスクトップ側だけです。コンソールのオートメーションページでは一覧と実行ができ、その下の折りたたみ式のアバターショートカットセクションにメインモデルのショートカットが並びます。デスクトップで一時停止したオートメーションは一時停止中と表示され、実行できません

Stream Deck

Stream DeckプラグインはこのAPIのもう1つの公式クライアントで、モデルとシーンの切り替え、ホットキー、表情、モーション、そしてアバターの移動や拡大縮小を物理キーで操作できます

MCPサーバー

@laplace.live/persona-mcpは3つ目です。Model Context ProtocolのサーバーとしてこのAPIをAIアシスタント——Claude、Cursor、Codex——に渡し、タスク単位の20個ほどのツールとして提供します。それ以外は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));

すべてのメソッドは1つの共有テーブルで型付けされているので、呼び出しのリクエストとレスポンスの形はメソッド名から決まります。SDKリファレンスでは、インストール、クライアントのオプション、認証、パラメータリース、そしてエクスポートされているすべての型を扱っています

イベント

セッションは購読したイベントのみ受信します。SDKは再接続後に購読を自動で復元します

イベント発火のタイミング
scene.changedシーンへのあらゆる変更:作成、削除、名前の変更、適用、編集
scene.loadingシーンの適用やパイプラインのウォームアップの開始と終了
settings.changedアプリの設定が変わったとき
instance.loadedモデルインスタンスのステージ上での読み込みが完了したとき
selection.changed編集の選択対象が移ったとき。どこからの操作でも
expression.changed適用中の表情の組み合わせが変わったとき
expression.persistenceモデルの「表情を記憶する」フラグが切り替わったとき
motion.startedモーションの再生が始まったとき。motion-stopを持つホストではoneShotも付きます
motion.endedモーションの再生が終わったとき
speech.startedspeech.playの発話が始まったとき
speech.ended発話が終わったとき——再生完了、停止、上書きのいずれでも
hotkey.stateホットキーの設定が変わったとき
automation.stateオートメーションの一覧・名前・トリガーの種類・有効状態・OS登録状態が変わったとき
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.*それぞれのlistregister、それにregistry.thumbnail
settings.*get patch
tracking.* / pose.*tracking.addSource tracking.updateSource tracking.removeSourcesetEnabledsetSource、加えてpose.setPorttracking.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.*で扱います。enabledfalseのライトは影ごと消えますが、ほかの設定は保持されます。このフィールドの既定値はtrueで、ライトをオフにできないビルドは送ってきません

vrmCameraは丸ごと置き換わります。orbitfov(1 – 179°)、roll(視線の軸まわりの回転、ラジアン)、projectionperspectiveorthographic)、clipAssetIdです。古いビルドにはrollprojectionがなく、0とperspectiveとして扱われるので、これらのコントロールを出す前に返ってきたカメラを確認してください。オービットの角度は任意のラジアン値を、distanceは負の値も受け付けますが、マウスでの操作は従来の狭い範囲のままです。平行投影のビューは幅がabs(distance)になり、fovは保持されますが効かず、distanceが負だと両方の軸が反転します。stage.resetCameraはロールと投影もリセットします

object.addは省略可能なplace2dplace3dを受け取り、オブジェクトは既定の配置で1フレーム描かれることなく、同じ編集の中でその配置に置かれます。値はobject.setPlacementと同じく範囲内に丸められます。object.addMany { objects }は同じ形のエントリを最大100個、1回のシーン編集として追加し——保存も取り消しも1回分です——instanceIdsをリクエストの順で返します。解決できないアセットが1つでもあると、何も追加されません

instance.attach { instanceId, attach }はLive2Dインスタンスをアイテムとして別のLive2Dモデルにピン留めします。attachobject.attachと同じ形で、nullを渡すとその場で解除されます。attach.depth{ kind: 'front' }{ kind: 'behind' }{ kind: 'artMesh', id }のいずれかで、最後のものは親モデルのそのアートメッシュのすぐ上にアイテムを差し込みます——親にないIDは前面として扱われます。attach.split、つまり{ itemArtMesh, depth }は、アイテム自身のアートメッシュの1つで切り分け、その下の部分を2つ目の深さへ送ります。object.anchorsの各行にはorderが付きます。リストを取得した時点でのそのアートメッシュの描画順で、深さのコントロールはこれで段を並べます。輪になるピン留めはinvalid-paramsを、VRMインスタンスへの呼び出しはunsupported-for-formatを返します。オブジェクトでは、今のところfrontだけが有効です

stage.capturestage-captureケイパビリティを必要とし、{ dataUrl, width, height }を返します。ステージウィンドウの表示そのままで、アルファ付きのPNGです。最長辺がmaxEdge(64 – 2048、既定値1024)を超えないよう縮小され、拡大は行いません。画面を見られないクライアント——MCPサーバー経由のAIアシスタントなど——が自分の編集を確かめる手段です。1回のキャプチャごとにレンダリングが1フレーム止まるので、必要なときだけ取得し、ポーリングはしないでください。renderer-unavailableはステージウィンドウがなかったか、コピーできるフレームがなかったことを意味します。クラッシュしたステージは再読み込み後に描画するまでこれを返すので、諦めずに再試行してください

ケイパビリティ

対応機能はアプリとインスタンスそれぞれのケイパビリティ一覧で確認できます。バージョン番号を比較するのではなく、この一覧を使って判定してください

アプリ自身のものはhelloapp.infoが報告します——現在はstoragespeechautomationslayer-effectsscene-transitionsarea-lightsspot-lightscamera-follow-lightsshadow-filtersenvironment-map-modelspawntracking-lostmotion-stopstage-capturecontrollersmodel-editingasset-inspectionです。各インスタンス固有のものはinstance.listcapabilitiesにあり、どのケイパビリティにも含まれないメソッドはunsupported-for-formatで拒否されます

後半の3つはそれぞれ共有エディタのメソッドを開きます。controllerscontroller.*——接続中の機器と保存済みプロファイルの読み取り、改名、デッドゾーンの設定、削除、割り当ての開始——と、settings.patchから書くcontroller.enabledのマスタースイッチです。機器はデスクトップに接続されているものであって、ブラウザが動いているマシンのものではありません。model-editingbinding.*(モデルのパラメータバインディングの読み取り・プレビュー・確定・解放と、短時間の入力オーバーライド)とinstance.setBreathです。binding.inputs{ inputs, outputs }を返し、inputsは現在のトラッキング入力、outputsは各バインディング先のパラメータがモデル上でいま取っている値を出力idごとに返します——モーション・表情・物理演算まで適用した後の値で、読み取れないものは省かれます。asset-inspectionscene.inspectregistry.thumbnailです

instance.setControllerMovementはインスタンスのコントローラー移動の設定をマージします:enabledslot(保存済みプロファイルの番号)、moveSpeedturnSpeedsmoothing、VRMではさらにwalkEnabledwalkClipwalkSpeedfaceMovementです。範囲外の値は既定値か境界に丸められ、オブジェクトはunsupported-for-formatを返します。walkClipinstance.setIdleと同じ参照を受け付けます

モーションとアイドル

motion.listはモデルのモーショングループを返します。Live2Dモデルでは、model3.jsonが宣言していない.motion3.jsonもモデルフォルダーからすべて列挙され、それぞれがファイル名を名前とするグループになります。デスクトップのモーションセクションで記録したモーションが再読み込みなしで現れるのはこのためです

motion.stop(アプリのケイパビリティmotion-stop)は再生中のモーションをフェードアウトさせ、アイドルに戻します。アイドルしか再生していないときは何もせず、{ stopped: false }を返します。motion.playingoneShotmotion.startedにもあります)は、報告されたモーションがアイドルより優先されるもの——つまりstopが終わらせるもの——かどうかを示します。古いビルドではこのフィールドはありません

instance.setIdleはインスタンスのアイドル設定をマージします:

フィールド意味
idleAnimationアイドルのマスタースイッチ。falseはVRMのクリップを止め、Live2Dではモデル自身のIdleグループも含めてすべてのアイドルモーションを止めます
idleClipVRMのみ。アイドルクリップの参照
idleMotionLive2Dのみ。インスタンスのケイパビリティidle-motionsが必要です。motion.listにあるモーションファイルを他のすべてのモーションの下でループします。nullはモデルのIdleグループをランダム再生します。モデルが列挙しなくなったファイルはnullと同じ扱いです
trackingLostBehaviortracking-lostが必要。holdは最後にトラッキングした姿勢を保ち、idleは約0.3秒かけてアイドルへ戻り、顔が戻ればまた戻ります
trackingLostMotiontracking-lostが必要。Live2Dのみ。顔が十分な時間見えなくなったらアイドルの代わりに再生するモーション。nullはアイドルのまま
trackingLostDelaytracking-lostが必要。その「十分な時間」の秒数、0〜60

instance.getはこれらをすべて報告します

ライティング

area-lightsケイパビリティを持つビルドは、種類がareaSceneLightを受け付けます。x/y/zに置く長方形で、azimuth/elevation(度)で向きを、roll(−180 – 180°、既定値0)で自身の面内の回転を、widthheight(それぞれ0.01 – 20シーン単位、既定値1)で大きさを決めます。PBRマテリアルとMToonのアバターを照らし——MToonはトゥーンシェーディングの中で4つのライトサンプルとして近似します——Live2Dには効かず、影も落としません。rangeと影の設定は、あとで種類を変えるときのために保持されます

spot-lightsケイパビリティを持つビルドは種類spotを受け付けます。x/y/zazimuth/elevationrange(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——targetXtargetYtargetZdistanceとワールド空間のrotationクォータニオン——を使い、その値はオフにした時点で固定されます。参照がなければ、注視点はゼロ、回転は単位回転、距離はゼロとして扱われます

scene.setLightFollowCamera { lightId, followCamera, options? }は、アクティブなシーンのライト1つの追従を切り替えるか、optionsをその選択にマージします。ライトは動かず、向きも変わりません。デスクトップは画面上のカメラ(再生中のカメラモーションを含む)に対してライトの座標を換算し、換算後の設定を{ light }で返します。ライトがもう存在しなければlight: nullです。scene.patchと保存済みのシーンは、書かれた値をそのまま使い、この換算はしません。フィールドもメソッドもcamera-follow-lightsで判定してください

SceneLight.volumetricは、ポイントライト、スポットライト、エリアライト1つごとに、光に照らされる霧をオンにします。既定値はfalseで、ほかの種類は無視します。古いビルドはこのフィールドを送らず、代わりにシーン全体で1つのスイッチを持つので、フィールドがあるか確かめてからコントロールを出してください。そのスイッチをオンにして保存したシーンは、霧を照らせるすべてのライトでvolumetricがオンの状態で読み込まれます

SceneEnvironmentには省略可能なvolumetricLightingclusteredLightingの2つのフィールドが加わりました。古いビルドは送ってこないので、どちらのコントロールもフィールドがあるか確かめてから出してください。volumetricLightingはシーン全体の霧の見え方を決め、それ自体のスイッチはありません——点灯中のライトがどれも霧をオンにしていなければ、霧は出ません。現在のビルドは霧の設定をすべて返し、clusteredLightingを無効に補正します。編集はscene.patchで環境ごと行います

volumetricLightingのフィールド既定値
density0 – 101
intensity0 – 101
rangeカメラから1 – 100シーン単位20
qualitylowmediumhighmedium
speed0 – 5。0で霧が止まる0.2

霧はオンにしたライトのまわりで光り、深度で遮られ、照らされていない所は透明のままです。点灯中のシーンのライトが1つでも霧をオンにしていれば、3Dオブジェクトと環境モデルに含まれるポイントライト、スポットライト、エリアライトも加わります。透視投影のカメラが必要で、平行投影では設定は残りますが霧は描画されません。平行光源と環境光は関わらず、Live2Dも霧を遮りません。clusteredLighting: trueは、WebGPUの透視投影カメラで、範囲が有限で影を落とさないポイントライトが1 – 64個あるとき、表面のライティングを高速化します。範囲に上限のないポイントライトがある、数がそれを超える、あるいはレンダラーやカメラが対応していない場合は、通常のライティングのままです。影の描画コストは減らず、霧に使われるライトも変わりません

environment-map-modelを持つビルドでは、SceneEnvironmentiblAssetIdmodelAssetIdを同時に設定できます。このときbakeFromModelはマップを入力にしてモデルから照明を生成するかを選び、falseならマップで直接照らし、マップがなければモデル自身の空を使います。showSkyboxは表示だけを決め、どちらが照らしていても描くのはマップかその空です。片方のアセットを消してももう片方は残り、SDKのenvironmentClearPatch()がその編集を組み立てます。古いビルドは環境アセットを一度に1つしか持てないので、そこでは片方を設定するときにもう片方を消してください

さらに3つの省略可能なフィールドで、scene.patchからパノラマを調整できます。skyboxBlur(0 – 1、既定値0)とskyboxIntensity(0 – 2、既定値1)は見えているスカイボックスだけを変え、iblRotation(ラジアン、既定値0、1回転を超えて回り込んでよい)はパノラマとその照明をまとめて回します。モデルから生成する照明に使う空も含みます。古いビルドはこれらを送ってこないので、フィールドがあるときだけ対応するコントロールを出してください

物理演算

SceneEnvironment.physicsはシーンの物理演算のスイッチです。3Dオブジェクトがステージの床に落ち、VRMアバターの上にも着地します。既定値はfalseで、古いビルドは送ってきません。シミュレーション中の姿勢は保存されないので、読み返したオブジェクトの配置は書いたとおりのままで、physicsをオフにするとすべてのオブジェクトが元に戻ります

spawnケイパビリティを持つビルドはstage.spawnも受け付けます。登録済みのpropアセットを複製し、物理で動く物体としてステージに降らせるメソッドです。複製はレンダラーの中にだけ存在し——シーンのアイテムにもレイヤーの行にもならず、取り消しも保存もされません——同じファイルの複製はジオメトリ、テクスチャ、ドローコールを共有するので、数百個あっても軽く済みます。アクティブなシーンのphysicsがオフならinvalid-state、登録済みのpropではないアセットならnot-foundを返し、それ以外は{ spawned, alive }を返します。aliveはすべてのアセットの物体の数です

フィールド意味
assetId登録済みのpropアセット
count1 – 200、既定値1。ステージ上の物体が500個を超えると、古いものから消える
origin散らばらせる立方体の中心。{ x, y, z }をメートルで指定。既定値は{ x: 0, y: 3, z: 0 }で、アバターが立つ位置の上
spread散らばらせる立方体の一辺。0 – 20メートル、既定値1
velocityすべての物体に共通の初速度。{ x, y, z }をメートル毎秒で指定し、各軸±50以内。既定では静止
scale0.01 – 100、既定値1
ttlMs物体が残る時間。0 – 600000ミリ秒、既定値30000。0ならクリアするまで残る
transition{ style, inMs, outMs }。この物体だけに使う表示・非表示のスタイルと、0 – 5000ミリ秒の出現・消失の長さ。省略したフィールドはシーンの設定を使う

範囲外の数値は境界に補正されます。物体はttlMsが切れたとき、別のシーンに切り替えたとき、physicsをオフにしたとき、またはstage.clearSpawned {}で消えます。stage.clearSpawned{ cleared }を返し、アセットを読み込み中の生成も取り消します

シーン切り替え

scene.activateは切り替え先のシーンが読み込まれてステージを引き継ぐまで待ちます——その間も元のシーンは動作し続け、編集もできます——が、切り替え効果の終了までは待ちません。新しい切り替えは保留中のものを上書きするので、レスポンスが報告するのは実際に有効になったシーンで、要求したシーンとは限りません。SDKはシーンの切り替えを120秒まで待ちます。requestTimeoutMsを指定した場合はそちらが優先されます

scene-transitionsケイパビリティを持つビルドは、各シーンの切り替え効果——そのシーンに入るときに再生される効果——をScene.transitionに持ちます。scene.patch { transition }はこれを丸ごと置き換えますが、再生はしません:

フィールド意味
typecutfadewipecircleimagevideoのいずれか
durationMs100 – 10000ミリ秒
colorフェード、ワイプ、円形で覆うカバーの色(16進数)
assetId登録済みの画像か動画、またはnull
switchPoint動画のどこでシーンが切り替わるか。0.05 – 0.95。ステージ全体を覆うフレームを選んでください
autoFade動画をフェードイン・フェードアウトさせる。既定はオフ
fadeInMs / fadeOutMsそれぞれ再生時間で0 – 10000ミリ秒、既定は300。切り替え点より前・後の長さが上限。0でそのフェードをオフにする

シーンの切り替えは、どの方法でも切り替え先のシーンの効果を使います。カット以外の効果はすぐに始まり、切り替え先の準備が整うまでステージを覆い続けます。読み込みが遅いときはdurationMsを超えて延長されます。動画はミュートで再生され、速度は長さに合わせて調整され、待つ間は切り替え点のフレームで止まります

表示・非表示

SceneEnvironment.itemTransition { style, durationMs }はシーンの表示・非表示の設定で、モデル、オブジェクト、生成された物体がどのように現れ、消えるかを決めます。古いビルドは送ってきません。styleglitch(裂け目と焼けを伴うディザディゾルブ、既定値)、dither(余分な効果のないディザディゾルブ)、pop(拡大縮小で現れて消える)、cutのいずれかで、durationMsは0 – 5000、既定値は300です。cutdurationMsの値にかかわらず変化せず、0cutと同じ扱いです。編集はscene.patchで環境ごと行います

レイヤーエフェクト

layer-effectsケイパビリティを持つビルドでは、個々のモデルやオブジェクトが独自のエフェクトを持てます。シーンに合成される前に適用されるものです。どのシーンアイテムもシーンと同じ形のeffectseffectLayersを持ち、instance.setEffects { instanceId, effects, effectLayers? }で編集します:

  • effectscolorlevelscolorWheelscolorShiftselectColorsgradientblurbloomdiffusionrimoutlinedropShadowの部分的な設定を受け付けます。省略した項目は今の値のままです
  • effectLayersを指定すると、追加済みエフェクトの一覧を置き換えます。有効なエフェクトは常に一覧に含まれます

レスポンスは補正後の結果です。値は範囲内に丸められ、未知のキーは捨てられます。形式が不正なエフェクトがあると、何も変更されないまま呼び出し全体が失敗します

レイヤーエフェクトがかかるのはモデルと3D空間のオブジェクトです。2Dオブジェクトはunsupported-for-formatを返します。保存された設定は残るので、空間を切り替えれば有効になります

トラッキングソース

Personaでは設定済みのトラッキングソースを複数同時に動かせます。settings.tracking.sourcesが一覧を返し、tracking.addSourcetracking.updateSourcetracking.removeSourceで管理します。instance.setTrackingSourcesはソースIDを使い、インスタンスのフェイス、ポーズ、ハンドのチャンネル(faceSourceIdposeSourceIdhandSourceId)を対応するソースへ割り当てます。nullを指定するとそのチャンネルのトラッキングが止まり、存在しないIDもnullと同じ扱いです。新しいインスタンスは各チャンネルの既定ソースに割り当てられ、1つのソースを複数のインスタンスで共有できます

instance.setTrackingSourceshandTrackingModeも受け付けます。armsではトラッキングした手がVRMの指に加えて腕と手首も動かし、fingersでは指だけを動かすので、腕はVMCやmocopiの体のトラッキングに任せられます

フェイスソースはpersona-iosifacialmocapvts-iosのいずれかで、省略可能なphoneIpで1台の送信元に固定できます。ポーズソースはvmcmocopiです。portを持つのはvmcmocopiifacialmocapで、別のソースが使っているポートは拒否されます——1つのソケットを共有できるのはifacialmocap同士だけです。persona-iosvts-iosのポートはプロトコル側で固定されています。廃止されたvts-ios-nativeはプロトコル上で拒否されます

mediapipeウェブカメラのソースです。作れるのは1つだけで、portphoneIpもありません。mediapipeオプションで3つのタスク——チャンネルごとのfacehandsbody——を切り替え、deviceId''で既定のカメラ)、mirrordelegateCPUGPU)を設定します。既定ではミラー表示でCPUを使い、顔と手をトラッキングして体はトラッキングしません。tracking.addSourcetracking.updateSourceは部分的なオブジェクトを受け付け、省略したオプションはそのまま保たれます。トラッキングした手は、注入にある手の入力も動かします

tracking.statusはネットワークのフェイスソースとポーズソースの集約状態に加え、設定済みソースそれぞれの状態をsourcesマップで返します。ウェブカメラも含まれます。tracking.statusイベントも同じ形で、1つのソースの状態だけが変わったときにも発火します

従来の単一ソース用メソッドは、引き続き各チャンネルの先頭のネットワークソースを扱います。tracking.setSourceはその種類を変更し、pose.setSourceは必要ならVMCソースを作成してポートを返し、pose.setPortはそのポートを変更します。tracking.setEnabledpose.setEnabledは今もネットワークのフェイスソースとポーズソースのマスタースイッチです。ウェブカメラは自身のenabledだけに従い、これはtracking.updateSourceで設定します。タスクの選択とアバターの割り当ては保持されます

マイクによるリップシンク

リップシンクは、デスクトップのマイクで口を動かします。マイクと入力デバイスの一覧はデスクトップ側のもので、ブラウザが動いているマシンのものではありません。音声もキャリブレーションのデータもAPIを通りません。解析結果は注入にある声の入力も動かします

メソッド効果
lipSync.state設定、キャプチャの状態(offstartinglisteningerror)、デスクトップの入力デバイス、リアルタイムの音量と母音のサンプル、進行中のキャリブレーションを読み取る
lipSync.configure部分的な設定——enableddeviceIdgain(0 – 30 dB)、noiseGate(−60 – 0 dBFS)、smoothing(0 – 0.3秒)——をマージし、保存された結果を返す
lipSync.restart次のフレームでキャプチャを再起動する。オフのマイクをオンにはせず、キャプチャの完了も待たないので、lipSync.stateをポーリングする
lipSync.calibrateキャリブレーションを1ステップ実行し、新しい状態を返す

同じ設定はsettings.lipSyncにも現れ、settings.patchでも書き込めます。キャリブレーションはデスクトップで選択中のマイクを使い、デスクトップのパネルと共有されます。startで下書きを始め、recordphonemeAIUEO、または背景ノイズのS)を添えてその音を2秒録音し、6つすべて録り終えたらpreviewで下書きを適用し、savecancelで終えます。resetは現在のマイクを同梱のプロファイルに戻します。録音はすぐに返ってくるので、進み具合はlipSync.stateをポーリングして確認してください。そのcalibrationが段階を表すphasereadyrecordingverifying)、録音中の音、録り終えた音を報告します。現在の段階に合わないステップはinvalid-stateになります

instance.setLipSync { instanceId?, mode }は、マイクでモデルを動かすかどうかを設定します。always(既定)、when-untracked(顔がトラッキングされていないときだけ)、offのいずれかです。オブジェクトはunsupported-for-formatを返します

音声

speech.playは音声を再生し、その音量で口を動かします。動作するのはspeechケイパビリティを持つインスタンスだけで、現在は読み込み済みのLive2Dモデルです。判断は形式ではなくインスタンスのランタイムのケイパビリティで行ってください。0.53以前のバージョンは、削除されたレガシーWebGLエンジンではこのケイパビリティを報告しません

パラメータ説明
urlhttps:http:(ローカルのTTSブリッジ)、またはインラインのdata:audio/*ペイロード
volume省略可能。0..1
instanceId省略可能。既定はシーンのメインモデル

1つのモデルにつき発話は1つで、新しい再生が現在のものを上書きします。呼び出しが返ってきたら再生が始まったということで、始まらなかった場合はinvalid-stateになります。speech.startedspeech.endedが発話を挟み、speech.stopで途中終了できます

オートメーション

automationsケイパビリティを持つビルドでは、アプリのオートメーション——ショートカット、イベント、リクエストから始まる一連のステージ変更——を一覧・実行できます

メソッド効果
automation.listすべてのオートメーションを列挙
automation.runidを指定して1つ実行

アクションの中身、トリガーの設定、編集はアプリ側に留まります。一覧が返すのはidtitleacceleratorregisteredenabled、そしてactionKindstriggerKindsの配列です——各アクションが何をするかを知らなくても、ボタンを一列描くには十分です。titlenullのときはactionKindsからラベルを組み立ててください。SDKのautomationLabelがやっているのがまさにこれです。actionSceneIdsactionKindsと位置が対応し、各switch-sceneの切り替え先シーン(ほかの種類はnull)を持つので、ラベルにシーン名を出せます——ただし、そのシーンはすでに削除されているかもしれません

オートメーションはどれもタイムラインで、そのタイミングはほかの中身と同じくアプリ側に留まるため、actionKindsの順序は実行の順番を表しません。アクションの種類には、タイムラインの開始前に準備として実行されるswitch-sceneload-model、一時エフェクトのeffect-clipplay-camera-motionstop-camera-motionplay-audioaudio-control、そしてアバター向けのtoggle-expressionplay-motionremove-all-expressionsload-modelmodel-positionがあります。delayはなくなりました——タイムライン上の空白がその役目を果たします。音声には専用のメソッドがなく、ファイル・再生・出力デバイスはデスクトップ側に留まります。クライアントから音を鳴らすには、オートメーションを実行します。triggerKindsは、ショートカット以外にそのオートメーションが持つイベントトリガーの種類を並べたもので、現在はscenemodel-loadedmotionface-trackingmicrophoneparameterです

キーボードやコントローラーのショートカットが割り当てられていないとき、acceleratornullになります——automation.runからは変わらず実行できます。一時停止中のオートメーションはenabledfalseで、automation.runを含むすべてのトリガーを無視します。automation.runは実行を送り出した時点で返り、アクションの完了は待ちません。一覧・名前・トリガーの種類・有効状態・OS登録状態のいずれかが変わるたび、automation.stateが一覧をまるごと送り直します

プラグインストレージ

storage.*はプラグインに永続的なキーバリューストレージを提供し、名前空間はAPIキーごとに分かれます——キーがプラグインの身元であり、同じキー上のすべてのセッションが同じデータを共有し、キーを失効させるとデータも削除されます。値は任意のJSONです

メソッド効果
storage.getキーを読む。一度も書いていないキーはvalue: nullを返す
storage.setキーに書き込む
storage.deleteキーを削除する。存在しないキーでも成功する
storage.listすべてのキーをソートして列挙する

上限はキー名が128文字、シリアライズ後の値が1つあたり64 KB、APIキーあたり256個のキーです。キー数の上限を超えるstorage.setinvalid-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それ以外のすべて

このコードの集合はプロトコルの一部です。クライアントは未知のコードを持つエラーフレームを破棄するので、新しいコードはプロトコルのバージョン更新とともにしか現れず、新たな失敗は既存のコードを再利用します

切断

クライアントは予期しない切断のあと、自動で再接続します。ただし、以下のクローズコードでは、キーの失効やユーザーによる切断を尊重して自動再接続を停止します:

コード定数原因
4001CLOSE_KEY_REVOKEDキーが失効した
4002CLOSE_FORCE_DISCONNECTEDユーザーがそのセッションを切断した

どちらの場合もクライアントは最終的にclosed状態に落ち着きます。onCloseが指定されていれば終端的な切断はそちらへ通知され、onWarningは呼ばれません。onCloseがなければonWarningへフォールバックします。1001はこれに含まれません——サーバーが停止中であることを意味するので、復帰したら再接続してください

キーを失効させると、送信待ちのフレームは直ちに破棄され、そのキーを使う接続は4001で閉じられます。ステージの応答を待っているリクエストは書き込みを再開しません。すでにステージへ送信された操作は完了する場合がありますが、そのレスポンスは破棄されます

バージョンの不一致

プロトコルはバージョンを持っており、接続先のビルドと一致しない場合、SDKは警告を出します。古いPersonaが知らないイベントを購読しても致命的ではありません——SDKは1つずつ購読する方式にフォールバックし、通ったものを保持して、残りについては名前を挙げて警告します

現在のプロトコルは4です。これまでのバージョン更新ではいずれもワイヤーから何かが取り除かれたので、古いプロトコル向けに書かれたクライアントやプラグインは更新が必要です:

プロトコル変更点
2Scene.behavior(カーソルを目で追う)が、シーンのデータとscene.patchの両方から削除された
3stage.shockwaveが削除された。呼び出すとunknown-methodになる
4shortcut.listshortcut.triggershortcut.stateautomation.listautomation.runautomation.stateになり、shortcutsケイパビリティはautomationsに改名された。ペイロードではautomationIdautomationsを使う

最終更新日:2026年9月20日

Tech otakus destroy the world