Live Studio
jp.lilium.livestudio の変更履歴です。
[0.25.3] - 2026-07-22
Added
- ライブプロジェクトを開くときに、未保存のライブシーンの編集を破棄してよいか確認するようになりました(Save / Don't Save / Cancel)。以前は黙って破棄していました。プロンプトは
RemoteConfirmSystemを通じて上げられるため、マシン上と、そのライブプロジェクトを要求したリモートアプリの両方に表示されます。「名前を付けて保存」をキャンセルした場合は、ユーザーが残すと選んだ編集を破棄せず、開く操作自体を取りやめます。
Fixed
- ライブプロジェクトを開いたあとのアプリの状態が、そのライブプロジェクトで起動した場合と同じになりました。以前は、直前に開いていたライブプロジェクトが持ち越されていました。
OpenProjectは通常のライブシーン読み込みを再利用しており、これは読み込むシーンが別のベースシーンを指す場合にしかベース Unity シーンを再読み込みしません。そのためベースシーンを共有する 2 つのライブプロジェクト間では再読み込みが完全にスキップされ、前のライブプロジェクトで読み込まれたプロップ/アバターがそのまま残り、読み込む(差分)シーンファイルが省略した値もすべて維持されていました。ライブプロジェクト単位の設定はさらに悪く、そもそもシーンファイルに含まれず加算的に適用されるため、新しいライブプロジェクトが記録していない設定は前のライブプロジェクトの値を保持していました。LiveSceneManager.OpenProjectSceneは、復元の前にすべての公開オブジェクトを取得済みの既定値へリセットし、ベースシーンの再読み込みを強制するようになりました。ライブプロジェクトフォルダのクロールもリセットの後ろへ移したため、前のライブプロジェクトで有効化・読み込み済みだったカタログのエントリ——クロールは意図的にこれらを削除しません——が切り替え後に残ることもなくなりました。
Changed
- 組み込みアセットカタログが
AnimationClip専用ではなくなりました。Resourcesフォルダから焼き出すアセット型はBuiltinAssetTypeRegistry(AssetTypeRegistryの組み込み版)で決まります。各 kind が、担当する Unity のアセット型と、一覧に出すAssetBaseのエントリを宣言するため、パッケージはベイカーやランタイムのレジストリに触れずに追加できます。BuiltinAssetCatalogは型ごとの配列ではなく、所属 kind を名乗るエントリの単一リストを持ちます。BuiltinAssetCatalogBuilderは登録済みの kind ごとに 1 回走査し、ファイル拡張子ではなくアセット型でインポートを分類し(kind が自分の型の取りうる拡張子を列挙せずに済みます)、エディタ読み込みごとに 1 回再構築します——新しく登録された kind を拾うのはこの再構築です(kind を知らせるアセットインポートは発生しないため)。BuiltinAnimationAssetの参照リソースとしての挙動(読み込み/解放のトグルなし、削除されない、永続化されない)は共有のBuiltinAssetBaseへ移り、各 kind は自身の公開@typeを持ちます。既存の焼き込み済みカタログは、次のエディタ読み込み時に新しい形へ書き換えられます。
[0.25.2] - 2026-07-21
Fixed
ChildProcessHost経由で起動した子プロセスを、kill-on-close のジョブオブジェクトでホストの寿命に紐付けるようにしました。従来はすべての正常停止の経路がマネージドのクリーンアップから走っていたため、巻き戻し(アンワインド)せずに死んだホスト(クラッシュ、タスクの終了、終了ウォッチドッグ)は、フュージョンとリモートアプリを孤児化させ、それらがポートを掴んだまま/ビルド出力をロックしたまま残っていました。StartChildApplicationも、プロセスの起動に失敗したときは、そのまま使い続けずに早期リターンするようになりました。ExpressionEntry.weightが、配列差分の生成する空名のテンプレートインスタンスで例外を投げなくなりました。FacialKeyは空のカスタム名を拒否し、駆動すべき expression スロットも無いため、このプロパティは0を返し、書き込みを無視します。この例外はwantsToQuitを抜けてしまい、Unity は未保存チェックが一度も走らないまま終了を通していました——これは一見、終了が成功したように見えますが、そうではありません。
Changed
- 描画品質の設定を、静的な
LiveSceneManagerクラスから、シリアライズ可能なIExposedObject(StageManagerと同様)であるRenderQualityへ移しました。リモートアプリの設定ページに品質セクションを表示するかどうかは、登録によって決まるようになりました。設定のNavigatePageはRenderQualityの id を列挙し、NavigateObjectSelectorは何にも解決しない id をスキップするため、アプリはRemoteControlContainer(またはホストのRemoteControlBehaviour)のオブジェクト一覧にRenderQualityを置くことで品質コントロールを露出し、インスタンスを外せば隠せます。Live Studio Systemプレハブは既定で 1 つ登録します。LiveSceneManager.quality/.qualityNames/.currentQualityIndex/.SetQualityは削除され、永続化されるレベルはLiveSceneManager.settings.jsonからRenderQuality.settings.jsonへ移ります(レベルは一度だけライブプロジェクト既定にリセットされます)。
[0.25.0] - 2026-07-17
Added
AddSwitchAvatarOperationが、アクティブなアバターを切り替えるオペレーションセットを作成します。デッキタイルの全面背景に、そのアバターのサムネイルが設定されます。DeckControlにbackgroundAssetIdが追加され、可搬なライブプロジェクト相対参照として保存される(AvatarImageHandlerが解決)ため、保存したデッキはライブプロジェクトを移動したり別のマシンで開いても維持されます。InvokeFunctionOperationが、引数を取る公開関数やネストした関数を呼び出せるようになりました。ターゲット上の無引数関数だけでなく、位置引数を JSON 配列(argsJson)として、任意のpropertyPath(例:StageManagerのセット要素のWarpTo)とともに保存します。AddFunctionOperationに末尾の任意引数argsJson/propertyPathが追加されましたが、既存の無引数オーバーロードはソース互換のままです。VRCAvatarが、VRCFTAvatarと同様にAvatarBodyDriver(PlayableGraph)を通じて body アニメーション・トラッキングのゲーティング・メッシュの表示・下半身ロックを駆動するようになりました。これにより VRChat アバターでも、未トラッキング部位の body override クリップと下半身のポーズロックが使えます。ビセーム/音声と表情のパラメータは、ラップしたコントローラーの playable を通じて読み書きされます。- 組み込みアニメーションアセットのカタログを追加しました。
Resourcesに同梱されたAnimationClipはBuiltinAssetCatalog(Editor のBuiltinAssetCatalogBuilder)に焼き込まれ、BuiltinAnimationAssetリソースとして公開されます。BuiltinAssetRegistryが各クリップを GUID でAssetRegistryに、先行して冪等に登録するため(再生開始時・エディタ読み込み時・オンデマンド)、永続化された body override の参照がシーン復元時に同期的に解決されます。カタログのエントリはライブプロジェクトのアセット一覧に注入されisBuiltinが付くため、ExternalAssetManagerがそれらを削除・永続化することはなく、除去は拒否されます。 AvatarControllerの body override スロットが、インスペクタの_bodyOverrideClipPresets配列(削除されました)ではなくGET /api/assets?type=AnimationClip(Resourcesの組み込みクリップと外部の*.anim.lsbバンドル)から候補を取得するようになりました。VRCFTAvatarが_bodyOverrideClipをシリアライズフィールドとして公開し、Initialize/OnValidateで転送するようになりました。AvatarExpressionConfig.syncBlinkは、左右の瞬きウェイトを小さい方に揃えます。アバターによっては左右の目で瞬きウェイトの精度が非対称で、瞬きが左右で偏ることがあります。これを有効にすると左右対称に瞬きします。LiveStudioOrbitalFollow: 単一のターゲットを球面上で周回する Body ステージの Cinemachine コンポーネントです(yaw/pitch/distance、位置ダンピングとローカルフレームのターゲットオフセット付き)。カメラ自身の親フレームで解決されるため、カメラの親を回転させると周回リグ全体が回転します。OrbitalFollowCameraControllerはこれを通じて位置決めし、位置と注視の両方に単一のトラッキングターゲットを使うようになりました。- Studio Template のシーンに、最初から
OrbitalFollowカメラが含まれるようになりました。
Changed
- オペレーション駆動のプロパティ経路から、毎フレームの GC とヒッチを排除しました。
SetPropertyOperationは解決済みのExposedPropertyをキャッシュし(型付き読み取りに失敗したら自己修復)、毎フレームのbool/floatの書き込みに、FindPropertyを毎フレーム再走査して要素パスやコンポーネント配列を確保する代わりに、ボックス化しない型付きアクセサを使います。AvatarControllerは expressions 配列をキャッシュし(アバター/AvatarItemの変更で無効化)、キーつき配列パスの解決時の O(N^2) の GC を回避します。またInvalidateExpressionsからレジストリのキーつきコレクションの世代を進め、expression の要素が再構築された後にキャッシュ済みの解決が再解決されるようにして(古いキーへの書き込みを防止)、OnPropertyChangedを、T ポーズ/ソケットの再構築を毎フレーム走らせて数ミリ秒のヒッチを起こしていた_PostSetupAvatar全体の代わりに、変更されたプロパティだけを再適用するように絞り込みました。カスタムのFacialKeyのハッシュ計算もアロケーションフリーになりました。 - Fusion の UI Definition が、キャプチャーページをライセンス設定より前に並べるようになりました。
AvatarControllerが作成するアバター装着ソケットにS_プレフィックスを付けるようにしました(S_Hips/S_Spine/S_Chest/S_Head/S_Neck/S_WristLeft/S_WristRight)。同名のボーンがソケットを隠せなくなります。名前ベースの参照も更新しました(PropAttachmentの既定ソケット、bone-follower / look-at / orbital-camera のS_Headターゲット)。旧いソケット名を参照していたプロップやカメラは選び直しが必要です。
Fixed
- 下半身ロックが、body override クリップの「Root Transform Position (Y)」オフセット(ヒューマノイドのマッスルクリップの
level設定)を尊重するようになりました。AvatarBodyDriverは、applyRootMotionを無効にしたままAnimationClip.SampleAnimationでロックした腰の位置と足 IK ゴールを焼き込んでおり、このオフセットが暗黙に落ちていました。そのため Y オフセット付き(腰を沈めるため)で作った座りクリップは、オフセットなしの高さでロックされて浮いていました(オフセットが 0 のクリップは問題なく見えていました)。ロックのオフセットと足ゴールは、ルートモーションを有効にして取り直すようになり、クリップの Y オフセットが適用されます。ロック経路外で使う基本ポーズは変更ありません。 - モーメンタリなデッキボタンが、素早いタップでときどきアクションを取りこぼさなくなりました。押下と解放は 2 つの REST 呼び出しとして届きますが、両方が 1 回の
Updateフレーム内に収まると、マネージャがheld=trueを一度も観測できず、解放トリガーが黙って失われていました。SetHeldは立ち上がりエッジで解放パルスをラッチするようになり、ちょうど 1 回だけ発火します。 - 下半身ロックが、腰の親に回転を持つリグ(X=-90 でインポートされた Blender の Z-up アーマチュアなど)で頭を左右に振らなくなりました。ルートのヨー補償を腰のローカル回転に前置していたため、ワールドのヨー差分がロールに化けていました。現在はリグの親チェーンに依存せず、腰のワールド回転にワールド空間の差分として適用されます。
- 下半身ロックが、
humanScaleが 1 でないアバターで、膝軸が縮退したまま脚を完全に伸ばしきらなくなりました。足の IK ゴールは生のルートローカル位置として取得される一方、ロックされた腰は humanScale で正規化されていたため、腰から足までの距離が変わりクリップの脚ポーズが到達不能になっていました。ゴールは現在、サンプリングした腰からの相対で取得され、正規化されたロック腰のオフセットに再ベース化されます。 - 下半身ロックの高さがアバターの身長でずれなくなりました。
AvatarBodyDriverは、humanScale で正規化したルート相対のオフセットをワールド空間で適用して、腰を override クリップの腰位置にロックします。 QuitTerminationGuardが、終了時にマネージドのウォッチドッグスレッドではなく、切り離したウォッチドッグプロセスを起動するようになりました。マネージドスレッドは、遅れて起きるネイティブのテアダウン(WGI)のハングより先に Mono ランタイムとともに死んでしまい、Player ビルドの Fusion が終了後も残留していました。テアダウン中に自身がデッドロックしうる発火時刻のログは削除されました。LookAtCameraControllerが、Cinemachine 3 でも再び自前で LookAt ターゲットを駆動するようになりました。CustomLookAtTargetを設定して、注視が(トラッキングターゲットへ暗黙にフォールバックするのではなく)割り当てた look-at ターゲットを使うようにし(Cinemachine 2 と同等)、破棄時にフラグをクリアします。
[0.24.3] - 2026-07-09
Added
AvatarControllerが、キャプチャーが追跡していない部位を override のAnimationClipで駆動できるようになりました。クリップはインスペクタのプリセットか、外部のアニメーションバンドル(*.anim.lsb。複数のクリップを同梱します)から、統一されたアセットキー(焼き込みアセットは素の GUID、外部はfile:<path>#<clip>)で選びます。キーは遅延解決され、シーン復元時と REST の書き込み後に再適用されるため、バンドルの非同期読み込みをまたいで選択が維持されます。VRM1 / VRCFT の再生に対応します。- 「下半身のポーズをロック」トグルを追加しました。腰とルートをキャプチャーのアンカーに足 IK つきでピン留めし、上半身はキャプチャーへの追従を続けたまま、下半身をその場に保持します。
- ライブプロジェクトごとのセッションログを追加しました。Unity のログが
{project}/.livestudio/logに、セッションごとに 1 ファイルとしてネイティブの Player.log と並んでミラーされます。ProjectPathsにGetLogDir/EnsureLogDirヘルパーが追加されました。
Changed
- オペレーションセットの手動ホールドと手動値が、シーンの再読み込みをまたいで永続化されるようになりました(従来はどちらもリセットされていました)。復元時にエッジのベースラインが復元後のホールドで初期化されるため、セットをオンのままにしたシーンを読み直しても、オペレーションを再発火させる立ち上がりエッジが作られることはありません。
Fixed
- 被写体がキャプチャーの視錐台から外れる際に、アバターのメッシュが点滅しなくなりました。アバタールートの valid バイトが body / face のトラッキングのビットマスク(body = MediaPipe、face = ARKit)になり、表示は非対称(両方の信号が落ちたときのみ非表示、face の立ち上がりエッジで表示)になったため、フレームごとの body の有効性の揺れがメッシュをちらつかせることはなくなりました。
[0.24.2] - 2026-07-05
Added
- エディタに、リモートアプリを起動/終了する ツールバーボタン を追加しました(ランタイムの
RemoteAppHostと同じ設定パス/引数・子プロセス管理で動作します)。 LookAtCameraController(ICameraController)を追加しました。TransformRef(ターゲット所有者名+ボーン名/パス)から解決したボーンを、カメラのLookAtターゲットに割り当てます。参照が変わったときやアバターを差し替えたときだけ再解決するため、アバター再読み込み後も LookAt 先のボーンが維持されます。変更するのはLookAtのみで、Trackingターゲットや Aim コンポーネントはそのまま残します。BoneFollowerコンポーネントを追加しました。TransformRefから解決したボーンに自身のトランスフォームを追従させ、アバター差し替え時に再解決します。LiveStudio のカメラパイプライン外(別のステージ/セットバンドルでオーサリングした Cinemachine カメラなど)でオーサリングしたカメラを、差し替え可能なアバターのボーンに橋渡しします。シーンをまたいだボーンへの直接参照が差し替え後に維持できないケースに対応します。AvatarControllerに、読み込んだアバターのアニメーションレイヤーをシーン単位で上書きできる機能を追加しました。ProjectManagerが、選択中/非選択のカメラプレビューのポーリング間隔設定(ライブプロジェクトスコープで永続化)を公開し、カメラプレビューを更新する頻度を制御できるようにしました。
Changed
- Value モードの Deck スライダーが、常に正規化した 0..1 の生値を書き込む代わりに、割り当て先プロパティの最小値/最大値の範囲にドラッグをマッピングするようになりました。これにより、たとえば 0..100 のプロパティにバインドしたスライダーで全域を駆動できます。正規化値は内部的に保持されるため、ゲージやエッジ検出には影響しません。
- 読み込み済みのプロップ/アバターオブジェクトを、ライブシーンのトップレベル差分を唯一のソースとして永続化するようにしました。所有アセットの読み込みが完了していない状態はキューされ、アセット到着時にバインドされます。セッション中に一度もバインドされなかったエントリは、警告して破棄する代わりに、読み込み→保存のサイクルをまたいでそのまま保持されます。
Fixed
- シーンやプロップバンドルに直接オーサリングしたオペレーションセットに、初期化・復元時に安定した ID をバックフィルするようにしました。以前は既定の空 ID のままだったため、ID で指定する関数がすべて無言の no-op になり、入力マップの再構築時にセットがスキップされていました。
- 同じ内部 AssetBundle CAB を共有する複数の単一プレハブ・プロップを同時に読み込むと衝突すること("same files already loaded")がありました。バンドルのオープンを直列化し、ビルドした各バンドルにソースアセット GUID をシードとした一意の内部 CAB を与えることで、プロップが CAB を共有しないようにしました。
- ライブシーンの再読み込み時に、読み込み済みプロップ/アバターのオーバーライド(オーサリング位置から動かしたプロップなど)が失われないようにしました。読み込み完了時の再ベースラインが、適用済みの値をダーティ検出のベースラインに畳み込む代わりに、復元で適用したオーバーライドを保持するようになりました。
[0.24.1] - 2026-06-30
Added
- アクションセットを Deck(プッシュボタン / トグル / スライダーのコントロールを並べたグリッド)に配置できるようになりました。リモートアプリから自由に配置・編集できます。コントロールの種類はコントロールの配置時に選択し、アクションセットの入力モードとは独立しています。
- Value モードのアクションセットに手動の値オーバーライドを追加しました。スライダーコントロールで 0..1 の値を直接駆動できます(Studio へはスロットリングして送信)。
Changed
- アクションの「パネル」概念を全面的に Deck へ改名し、アクションセットのふるまいを単一のコントロール軸で駆動するようにしました。Deck のタイル幅はコントロール種別ごとに宣言され、欠落した Deck パネルは自動的に再生成され、タイルレイアウトのフィールドは汎用リモートエディタから隠されます。
Fixed
- アバターが非アクティブな間でも表情ウェイトを読み取れるようになりました。
KeyInputSourceのコントロールパスをバインディングのシャドウフィールドとして保持するようにし、キーバインドが正しく永続化・解決されるようになりました。- プレイモード開始時にアクティブなライブシーンのパスを起動時状態から再解決するようにし、最後に開いていたシーンが確実に復元されるようになりました。
[0.24.0] - 2026-06-26
Added
- アクションセット/入力バインドシステム(
ActionManager/ActionSet/InputSource/ActionBase)を追加しました。リモートアプリから編集でき、キーボードやゲームパッドの入力を、順序付きのアクション列(表情ウェイトの設定、アバター/ステージの切り替え、GameObject の表示切り替え)にバインドできます。多態的な入力/アクションは[SerializeReference]+[TypeSelector]を使い、入力モードは Button / Toggle / Value です。Live Studio Systemプレハブに組み込まれています。 InvokeFunctionActionとSetPropertyActionにより、任意の[ExposedFunction]や bool/float コントロールの隣に汎用の「キーへバインド」機能を提供します(安定した id でアドレッシング)。機能ごとの個別バインドを置き換えます。- アクションセットの相互排他トグルグループ: 空でない
groupを共有し入力が Toggle モードのセットは、ラジオグループのように振る舞います(1 つを ON にすると他が OFF になり、すべて OFF も許容)。 SwitchStageActionはステージを丸ごと切り替えます(SwitchToSetByNameが他の読み込み済みセットを取り外し、対象を必要に応じて読み込み)。ステージページのSetActiveSetは従来どおりの非排他選択の挙動を維持します。- アバターが座る椅子プロップ用の
AvatarChairコンポーネントを追加しました。AvatarControllerの下に再ペアレントしてアバターのルートモーションで引きずられないようにし、各パーツを記録した静止ポーズを基準にアバターの骨盤(Hips ソケット)へ追従させます。swivel/reclineは対象トランスフォームを作成時のローカル軸まわりに回転させ(Hips のヨー/ピッチ)、lateral/height/depthは軸に沿って平行移動させます(Hips の X / Y / Z)。静止ポーズはActivateアクションで記録します。各軸(ChairAxis)は可動範囲(min/max、0/0でロック)、ソースと追従対象の遊び(バックラッシュ)となるデッドゾーン(Hips の震えを吸収)、ダンピング(回転はSmoothDampAngle)を持ちます。 - ライブプロジェクト単位の状態とライブプロジェクトスコープ設定: 公開メンバーが永続化スコープ(Scene / Project)を持つようになりました。ライブプロジェクトスコープの値はクラスごとの
{Class}.settings.jsonに保存されます(画面出力のサイズ/全画面/Spout、ライブシーンの画質が Project スコープに)。StartupStateStoreがライブプロジェクトごとに最後に開いたライブシーンを記憶し(Settings/startup.json)、StartupSceneSwitcherが最初のシーン読み込み前にそこへリダイレクトします。 - 2 階層(メモリ+ファイル)のサムネイルキャッシュを、隠しの
.livestudioライブプロジェクトフォルダ(ProjectPaths)下に保存するようにしました。
Changed
- 破壊的変更: アバタープロップの
AvatarPropコンポーネントを、組み合わせ可能な兄弟コンポーネントに分割しました。新しい共有のProp(公開名"Prop"を維持。ソケット追従と位置/回転/スケールのオフセットを担う)と、ふるまいコンポーネントです。AvatarPropはAvatarItem(アバター→プロップのパラメータブリッジと表情駆動)に改名され、[MovedFrom]により旧型参照は解決され続けます。既存の*.prop.lsbバンドルは旧来の単一コンポーネントしか持たないため、再書き出しが必要です(再書き出ししたバンドルのルートはPropとAvatarItemの両方を持ちます)。ライブシーンの"Prop"状態キーは変わりません。 - 表情のキーバインドが、アクションシステムを通じて汎用的に駆動されるようになりました。
SetPropertyActionがexpressions[name].weight(データ駆動の表情スロット)を書き込むため、専用のSetExpressionAction/ExpressionBindingSystemと旧/api/expressionsバインドルートは削除されました。既存の表情キーバインドは作り直す必要があります。 - 共有の
FormatHeaderが、ライブシーン/ライブプロジェクト設定/プリセットの各ファイルでバージョン管理を統一します(生 JSON シリアライズ、孤立エントリの除去)。 - オブジェクトプリセット(
.preset.json)が、プロップとアバターの状態を差分として、寛容なリーダーで取り込むようになりました。 - Button モードのワンショットアクション(アバター/ステージの切り替え)が、キー押下時ではなくキー解放時に確定するようになりました(
ActionContext.triggered)。 ActionManager/ExternalAssetManager/StageManagerのシングルトンが、リモートアプリの汎用シーンオブジェクト一覧から隠されるようになりました(HideInScene)。専用ページからは引き続きアクセスできます。
[0.23.6] - 2026-06-23
Added
AvatarPropにscaleOffset(Vector3、既定1,1,1)を追加しました。プロップに設定されたローカルスケールに乗算されるため、アバターに装着したプロップの大きさをリモートアプリ/インスペクタから調整できます。毎フレーム適用され、位置・回転のオフセットと同様に unload/reload をまたいで保持されます。
Changed
- ステージマークが、単独の
AvatarStageControllerではなくStageManager経由でアバターをワープするようになりました。各SetBundleEntryが自身のセットシーン内のStageMarkラベルを公開し(セット単位にスコープされた新しいmarksフィールド)、StageManager.WarpTo(setId, markLabel)がそのセットのシーン内の名前付きマークへアバターのアンカーを移動します(空のラベルは原点へワープ)。
Removed
- 破壊的変更:
AvatarStageController(place/availablePlacesで読み込み済みの全マークから選ぶ「Avatar Placement」公開オブジェクト)を削除しました。ワープは上記の通りStageManager.WarpToでセット単位に行います。Live Studio Systemプレハブからも削除されています。
[0.23.5] - 2026-06-22
Changed
- オブジェクトのプリセットファイル(
*.preset.json)が、ライブシーンのファイル形式に合わせてjp.lilium.remotecontrol.presetのフォーマット識別子とformatVersionフィールドを持つようになりました。冗長だったsourceKindヒントは削除しました(ソースパスから導出されます)。
Removed
- 旧
prop.presetプリセット形式の後方互換読み込みを削除しました。この変更より前に保存したプリセットは保存し直す必要があります。
[0.23.1] - 2026-06-21
Fixed
- 起動のたびに Studio が未保存の変更を報告する問題(ライブプロジェクトフォルダにファイルがあると、未保存変更ダイアログで終了がブロックされる)を修正しました。
ExternalAssetManagerのアセット配列を直接永続化していたため、遅延実行されるライブプロジェクトフォルダのクロールが、ライブシーン保存の基準を取得した後にその配列を埋めていました。使用中のみを対象とする永続化シャドウを復元し、クロールで構築したカタログが保存/変更状態の対象に入らないようにしました。
[0.23.0] - 2026-06-21
Added
ExternalAssetManager: プロップ・アバター・セットバンドルを統一的に読み込み/解放する単一の実行時カタログ(旧PropManagerを置き換え)。アバター選択、プロップ読み込み、セットバンドル管理はすべてこれを経由します。- 実行時アバタープロップ:
.prop.lsbバンドルを実行時にアバターへ装着し、AvatarPropを介してボーン/ソケットに追従させられます。ソケット装着はアバターのリグやスケールに対して堅牢になり、プロップの公開オブジェクトのパラメータと id が unload/reload をまたいで保持されます。 - プロッププリセット: 読み込んだプロップの調整済みパラメータを
.preset.jsonとして保存し(SaveAsPreset)、新しいプロップとして再読み込みできます。プロップの既定値からの差分のみを保存します。 - ライブシーンのアセットとバンドルサムネイルを備えたライブプロジェクトアセットカタログ。書き出した
.prop.lsb/.avatar.lsbバンドルにはサムネイルが埋め込まれ、リモートアプリのアセットカードで使われます。 - アバターの VRM サムネイルを
/api/avatar/image?id=で配信するようにしました。UniVRM への依存なしに VRM 内蔵のサムネイルから抽出します。 - クロスシーンのリモート制御: 追加読み込みされたセットバンドルが、単一の常駐ホストサーバーにオブジェクトを公開します。新しいステージマーク(
StageMark/StageMarkRegistry/AvatarStageController)により、リモートアプリから名前付きマーク(および組み込みの Zero 原点)へアバターをワープできます。また、保存されたアクティブシーンが読み込み時に復元されます。 - アセットの追加時にライブプロジェクトへインポートするようにしました:
AddAssetは選択したファイルを、開いているライブプロジェクトフォルダのアセット種別ごとのサブフォルダ(Avatars/Props/Sets、種別ごとに解決)へコピーし、ライブプロジェクト内のコピーを登録します(名前が衝突した場合は(n)サフィックスを付与)。すでにライブプロジェクトフォルダ内にあるファイルはコピーせずその場で登録します。現時点では選択した単一ファイルのみコピーします。 - ライブプロジェクトフォルダを保存データの拠点にしました: 初回起動時に
Documents/<brand>/<project>を作成して開き、ライブシーンの既定の「名前を付けて保存」先として使用し、「保存フォルダを開く」でこのフォルダを開きます。
Changed
- リモート制御ホストとそのマネージャを、ベースシーンの再読み込みをまたいで破棄・再生成せずに常駐させるようにしました。これにより、シーン切り替え時もリモート接続とマネージャの状態が維持されます。Studio のプレハブとテンプレートはこの常駐ホストを前提に再構成しました。
VRCFTAvatarの表情をExpressionResolver経由で処理するようにし、変換したアバターにハンドジェスチャー表情を自動付与するようにしました。- 受信したポーズを、可変フレームレートのレンダー更新時に最も近い 2 つの受信 60fps フレーム間で時間補間するようにしました(
AvatarAnimationSystem.Lerp)。これによりアバターが滑らかに進み、フレーム保持時に SpringBone が震えなくなりました。 - 破壊的変更: シーンバンドルの概念を「set」、ワールドの概念を「stage」に改名し、バーチャルプロダクションの用語に合わせました(ステージはセット・プロップ・マークを内包します)。セットバンドルは
.set.lsbとして書き出されます。SceneBundleAsset→SetBundleAsset、SceneBundleLoader/LoadedSceneBundle→SetBundleLoader/LoadedSetBundle、SceneBundleExporter→SetBundleExporter(メニュー「Export Set Bundle (.set.lsb)」)、LiveStudioBundle.SceneExtension/IsSceneBundle→SetExtension/IsSetBundle、WorldManager→StageManager(公開関数AddSet/RemoveSet/SetActiveSet、公開プロパティsets)。従来の.scene.lsb拡張子は入力としては引き続き受け付けます(SetBundleAssetとして読み込み)が、書き出しでは生成されません。旧@type名(例:SceneBundleAsset/WorldManager)を参照する保存済みライブシーンは移行されず、保存し直す必要があります。そのような解決できないエントリは null の穴を残さず消えるようになりました。StageManagerには[MovedFrom("WorldManager")]が付いているため、シーン内の[SerializeReference]の配線は自動的に移行されます。 ExternalAssetManagerがアセット配列をライブシーンへ直接永続化するようにしました。ライブプロジェクトフォルダのクロールが読み込み時に無効化されたカタログを再構築するため、別途の永続化シャドウは削除しました。SavedPathsが基準ディレクトリを設定されたブランド名から導出し、保存データをライブプロジェクトごとのフォルダに整理するようにしました。従来の単一のSceneサブフォルダと独立したLiveStudioPathsInitializerを置き換えます(フォルダの初期設定はProjectManagerに移動)。
Fixed
ResetCameraがヨー/位置のオフセットを、ポーズ駆動のアバタールートではなくキャプチャーカメラチャンネルから導出するようにしました。これにより繰り返しリセットしても安定します。また、設定可能なカメラ高さ(既定 1.5m)により、仮想カメラを床に落とさず目線の高さに保ちます。- Arms Post Rig を
VRM1Avatarのときのみ追加するようにしました。 - ステージ/シーンの表示状態とアクティブ状態を起動時に正しく復元し、常駐アクティブエントリが復元時に確定するようにして、保存基準が復元後の状態と一致するようにしました(終了時に誤った未保存変更プロンプトが出ません)。
- 実行時に読み込んだアバターが、
PlayableGraphの構築から 1 フレーム後にアニメーションパラメータのオーバーライドを再適用するようにしました(コントローラーの既定値に戻りません)。また、VRMAvatarSetupSystemはIAvatarが既に存在する場合に重複した表情コントローラーを追加しないようにしました。
[0.22.0] - 2026-06-14
Added
- シーンバンドルのインポート:
.scene.lsbの AssetBundle を、実行時に追加(additive)で読み込めるようになりました。新しいRuntimeSceneManager/SceneBundleLoaderコンポーネントと共有のBundleBuildUtilityを追加し、LiveStudioBundleが複合拡張子を判別することで.scene.lsb(シーン)と.avatar.lsb(アバター)のバンドルが 1 つのパイプラインを共有します。 CaptureCameraControllerにchannelIndexプロパティ(ローカライズキーCAMERA_CHANNELINDEX)を公開しました。CaptureCameraTrackerが追従するキャプチャーカメラのチャンネル(0 または 1)を選べます。HumanoidPoseDataがボーンごとのトラッキング presence(bonePresences、0..1)を持つようになりました。AvatarBodyDriverのポーズジョブは、この重みでモーションのポーズをアバターのアニメーションにボーン単位でブレンドします。presence 1 のボーンはモーションの回転を完全に採用し、0 のボーンはアニメーションをそのまま流し、中間値は両者を slerp します。これにより、トラッキングされていない部位はAnimatorControllerのアニメーションを再生し続け、トラッキングされている部位はモーションに追従します。
Changed
ExternalAvatarSourceのファイル選択が、複合拡張子.avatar.lsb(従来は.lsb)でフィルタするようになり、アバターバンドルを.scene.lsbと区別します。旧.lsavatar拡張子も引き続き受け付けます。- アバターフレームがフレームごとに複数のキャプチャーカメラチャンネル(チャンネルごとに 1 つの
CameraData)を持つようになり、worldA / worldB のカメラを個別に伝達します。 VRM1AvatarとVRCFTAvatarが、毎フレーム Humanoid ボーンの Transform を直接書き込む代わりに、PlayableGraph(新しい共有AvatarBodyDriver)でボディアニメーションを駆動するようになりました。アバターに付けた任意のAnimatorControllerはグラフに組み込まれ、トラッキングがロストしている間はそのアニメーション(アイドルや ROM クリップなど)が再生され、トラッキング中はモーションのポーズで上書きされます。共有のトラッキング状態処理・メッシュ表示・アバタービルドの定型処理をAvatarBodyDriverとAvatarBuildNotifier.BuildAndNotifyに切り出しました。
Fixed
VRM1Avatar/VRCFTAvatarがBuildAvatar内でAnimatorを遅延解決するようにしました。同期的な.lsavatar読み込み時にStartより前に実行されることがあり、従来は animator が null のままエラーをログ出力していました。AvatarBodyDriverが、組み込んだAnimatorのapplyRootMotionを無効化するようにしました。コントローラーのルートモーションでアバター全体が床に沈む問題(VRCFT アバター)を解消します。
[0.21.3] - 2026-06-12
Changed
- 公開している
Lightの影トグルが、ハードシャドウではなくソフトシャドウ(LightShadows.Soft)を有効にするようにしました(プロパティのセッターとデシリアライズの両方)。影のエッジがなめらかになります。
[0.21.2] - 2026-06-11
Added
ChildProcessHost.RequestCloseAndReleaseを追加しました。終了シグナルを使わず、ウィンドウを持つ子プロセスへ WM_CLOSE を送り、終了を待たずに即座に解放します。
Changed
- Studio 終了時に、子プロセスの終了待ちでブロックしなくなりました。Fusion プロセスには終了シグナルを送って即座に解放し(
RequestStopAndRelease)、Remote アプリには WM_CLOSE を送って即座に解放します(RequestCloseAndRelease)。従来のように各プロセスで最大 5 秒WaitForExitを待つことはありません。 - Studio のビルド出力フォルダと exe 名を、プロジェクトフォルダ名から決めるようにしました。専用の VRC ビルドエントリーポイントと App VRC ビルドプロファイルのパスを廃止しています。
Fixed
SkyboxBackgroundが、Skybox/Cubemap シェーダーがプレイヤービルドから除外された場合に null シェーダーを伝播させる代わりに、エラーをログ出力するようにしました(ExposedObjectContainer.Initialize中に実行されるため例外を投げてはなりません)。
[0.21.1] - 2026-06-09
Added
ExternalAvatarSourceが、VRM に加えて AssetBundle ファイル(.lsavatar)からのアバター読み込みに対応しました(拡張子で自動判別)。
Changed
VRMAvatarSourceをExternalAvatarSourceに改名しました(既存シーン向けに従来の公開名は維持)。アバター読み込み APIRequestLoadVRMをIAvatarService/AvatarController/AvatarServiceでRequestLoadに改名しました。- モデルファイルのフィールドラベルを汎用化し、ヘルプテキストを VRM 専用の案内に絞りました。
[0.21.0] - 2026-06-08
Fixed
- Windows ビルドで、終了後にバックグラウンドプロセスが残ることがある問題(Windows.Gaming.Input 関連のネイティブシャットダウンのハングが原因)を修正しました。グレースフルシャットダウンが停滞した場合にプロセスを強制終了するウォッチドッグ(
QuitTerminationGuard)を追加しました。
[0.20.12] - 2026-06-04
Added
- 視線を VRM10 の
LookAtコンポーネントに委譲するようにし、アバターの目が直接駆動される代わりに設定した注視ターゲットを追従するようにしました。
[0.20.11] - 2026-06-03
Added
ChildProcessQuitSignal: 特定の子プロセス(PID で識別)を Windows の名前付きイベント経由でグレースフルに終了させ、ウィンドウなしの子プロセスが強制終了される代わりに自前の終了時保存を実行できるようにしました。- 選択した prefab アセットから missing script を削除する「Assets/Lilium Live Studio/Remove Missing Scripts」コンテキストメニューコマンドを追加しました。
Changed
- ウィンドウなしの子プロセスを停止する際に、終了を待たずに終了シグナルを送って即座に戻るようにしました(
ChildProcessHost.RequestStopAndRelease)。
Fixed
- パッケージの Readme インスペクターのボタン(言語切り替え・セクション操作・Install)が、パッケージを変更不可の git/レジストリ依存として取り込んだ場合でもクリックできるようにしました。
[0.20.10] - 2026-06-02
Added
netsh経由でインバウンド UDP 許可ルールを登録するWindowsFirewallヘルパーを追加しました。ルールはプログラムパスではなく待ち受けポートで識別されるため、ツールを移動・再インストール・別のパッケージキャッシュパスから配布しても 1 つのルールで動作します。ルールが存在しない場合のみ昇格を要求します。
[0.20.9] - 2026-06-02
Changed
- RemoteControl のハンドラーをインスタンス単位で登録し、ルートをコンストラクターで宣言するようにしました。
[0.19.1] - 2026-04-29
Added
- 初回リリース。
jp.lilium.virgo.studioから分離し、VTuber アプリ汎用の基盤(Camera / Lighting / Scene / Build / RemoteControl ベース / 共有 Localization)を、VirgoMotion 固有のモーション受信・アバター制御から切り離しました。