【VR・VRChat】VIVE Focus Vision トラブルシューティング書きなぐり
- 共通環境
- Ultimate TrackerをFocus Visionにペアリングしてワイヤレスストリーミングをプレイ中、読み込み画面や映像 / 音声の途切れ(スタッタリング)が頻繁に発生する
- Focus Vision本体にUltimate Trackerをペアリング時、ワイヤレスストリーミングをプレイ中にバッテリーのホットスワップを行うと、レジューム後接続していたUltimate Tracker複数台(1~2台)が再接続できなくなる(ことがある)
- VIVE Focus Visionコントローラーのサムスティックのタッチセンサーの感度が悪く、VRChatにおいてピースサイン等の親指を使用するジェスチャー操作が行いづらい
- 境界(プレイエリア)がナナメに傾いている
- 6個以上のUltimate Trackerを同時に使用する
- Focus Vision本体からUltimate Trackerのファームウェアをアップデートを行った際、プログレスが40%で止まり進行しなくなる
- VIVE Focusシリーズ用バッテリーが、VIVE公式ストアで販売していない
- VIVE Focusシリーズ用コントローラーとVIVE リストトラッカーを同時にペアリングしたい
- ストリーミングプレイ中にUltimate Trackerドングルの接続ダイアログが表示される
共通環境
・OS: Windows 11 24H2
・RAM: 32GB
・GPU: RTX 4060
・無線ルーター: NEC PA-WX11000T12 (5 Ghz) / NEC Aterm WG1400HP (5 Ghz)
Ultimate TrackerをFocus Visionにペアリングしてワイヤレスストリーミングをプレイ中、読み込み画面や映像 / 音声の途切れ(スタッタリング)が頻繁に発生する
環境
・Vive Hub: 2.3.3b
- VIVEストリーミング: 2.2.4
・Focus Vision: 7.0.999.326
・Ultimate Tracker: 1.0.999.169
対策(追記:2025/08/16)
・ストリーミングに使用する無線ルーターをNEC PA-WX11000T12からNEC Aterm WG1400HPに変更したところ、現象が発生しなくなった
対策(旧)
※Focus Vision FW 7.0.999.344にて、下記手順で改善しなくなった
・Vive Hubにて下記設定を行う(グレーアウトは恐らく影響のない項目)
- "パフォーマンス"タブ
- "ビットレート" > "120 Mbps"(私の環境では200 Mbpsを設定すると、稀にスタッタリングが発生した)
- "ダイナミックビットレート" > "オフ"
- "送信モード" > "TCP"
- "グラフィックス"タブ
- "ストリーミンググラフィックスの設定" > "自動"
- "鮮明化" > "+6"
- "パススルーMR" > "オフ"
・Ultimate Trackerを接続後に、"設定" > "接続設定" > "Wi-Fi"から別のアクセスポイントへ切り替え、元のアクセスポイントへ戻してワイヤレスストリーミングを開始または再開する
・無線ルーターのQoS設定でFocus VisionのPriorityを上げる
備考(旧)
私の環境では、ワイヤレスストリーミング開始前に上記Wi-Fiのアクセスポイントの切り替え、再接続(同ルーターの5 GHz - 6 Ghz間)の手順を挟むことでストリーミング中の通信が安定した
Focus Vision本体にUltimate Trackerをペアリング時、ワイヤレスストリーミングをプレイ中にバッテリーのホットスワップを行うと、レジューム後接続していたUltimate Tracker複数台(1~2台)が再接続できなくなる(ことがある)
復帰手段(追記:2025/08/16)
Ultimate Trackerドングルの抜去による再接続を行う
復帰手段(旧)
Ultimate Trackerの再ペアリングを行う
VIVE Focus Visionコントローラーのサムスティックのタッチセンサーの感度が悪く、VRChatにおいてピースサイン等の親指を使用するジェスチャー操作が行いづらい
コントローラーのサムレスト("/input/parking"の"タッチ")に"gesture_activator_thmb"をバインドする
境界(プレイエリア)がナナメに傾いている
・本体を初期化する
・Focus Vision本体前面のカメラ部分をタオル等で隠した状態で、"設定" > "境界"から"視界" / "フロアの位置" / "安全境界"のいずれかをリセットする(?)
> my floor is tilted on the focus vision, how do i fix that?
> the only way I know of fixing it is by throwing a sheet or something over your headset while you have it on to block the cameras, to trick it into resetting your boundaries/setup
https://discordapp.com/channels/946305475467706419/962856801555054613/1340811836672577566 (Discord VIVE公式コミュニティサーバー)
6個以上のUltimate Trackerを同時に使用する
Focus VisionまたはXR EliteとPCそれぞれにドングルを接続することで、Vive Space Calibratorを用いてFocus Vision (5) + PC (3)のように、6個以上のUltimate Trackerを同時に使用できる(らしい)
> can i use the xr elite + 6 ultimate trackers with pcvr?
> you can use 5 trackers connected directly to the xr elite and 1 to the pc
https://discordapp.com/channels/946305475467706419/1180030550476603493/1303291747165671426 (Discord VIVE公式コミュニティサーバー)
Focus Vision本体からUltimate Trackerのファームウェアをアップデートを行った際、プログレスが40%で止まり進行しなくなる
復帰手段(※保証はしません)
Ultimate Tracker FW 1.0.999.168 から、 1.0.999.169へのアップデートで発生
約1時間待機しても進行しなかった
ヘッドセットボタン長押しから本体の強制シャットダウンを行い、PCのVive HubからFWをアップデートすることができた
Ultimate TrackerのFWアップデートはVive Hubから行ったほうが無難そう
VIVE Focusシリーズ用バッテリーが、VIVE公式ストアで販売していない
リチウムイオンバッテリーのため、安全上の観点でVIVE公式ストア(台湾)から販売ができないとのこと
ビックカメラ、ソフマップ、コジマネットで販売している(2025年3月現在)
VIVE Focusシリーズ用コントローラーとVIVE リストトラッカーを同時にペアリングしたい
現状、FW 7.0.999.326ではできない
ストリーミングプレイ中にUltimate Trackerドングルの接続ダイアログが表示される
延長ケーブルもしくはコネクタ部分が断線 / 接触不良を起こしている可能性
私の環境では延長ケーブルの交換で改善された
【Unity】任意のAnimation Stateと現在再生されているStateを比較する
はじめに
Animatorのパラメーター/ステートは文字列ではなくハッシュ値で管理するとよい
(例)
protected Animator m_Animator; //~~~ m_Animator.SetTrigger("Attack");
ではなく
protected Animator m_Animator; readonly int hashAttack = Animator.StringToHash("Attack"); //~~~ m_Animator.SetTrigger(hashAttack);
の方が好ましい
現在のステートを取得する
AnimatorStateInfo、Animator.GetCurrentAnimatorStateInfoを使用する
protected AnimatorStateInfo m_CurrentStateInfo; //現在のハッシュ値が入る protected Animator m_Animator; void Awake(){ m_Animator = GetComponent<Animator>(); } void Update(){ m_CurrentStateInfo = m_Animator.GetCurrentAnimatorStateInfo(0); }
Base Layerのみを使う場合

protected AnimatorStateInfo m_CurrentStateInfo; protected Animator m_Animator; //State Hash readonly int hashStateLocomotion = Animator.StringToHash("Locomotion"); void Awake(){ m_Animator = GetComponent<Animator>(); } void Update(){ m_CurrentStateInfo = m_Animator.GetCurrentAnimatorStateInfo(0); //Base Layerのみの取得なので0を入れる Debug.Log(IsStateLocomotion()); } bool IsStateLocomotion(){ bool isState = m_CurrentStateInfo.shortNameHash == hashStateLocomotion; return isState; }
いくつかのLayerを組み合わせて使う場合
例としてBase Layerの他にAttack、Damage用にの2つのレイヤーを追加したもの(計3つのレイヤー)を使用する

複数のレイヤーからStateを比較するときはfullPathHashを使って比較する
protected AnimatorStateInfo[] m_CurrentStateInfo = new AnimatorStateInfo[3]; /* protected AnimatorStateInfo[] m_NextStateInfo = new AnimatorStateInfo[3]; protected bool[] m_IsAnimatorTransitioning = new bool[3]; */ protected Animator m_Animator; //Parameter Hash readonly int hashAttack = Animator.StringToHash("Attack"); //State Hash readonly int hashStateLocomotion = Animator.StringToHash("Base Layer.Locomotion"); //Layer名.State名 readonly int hashStateAttack_1 = Animator.StringToHash("Attack.AttackSM.Attack_1"); //Layer名.StateMachine名.State名 void Awake(){ m_Animator = GetComponent<Animator>(); } void Update(){ for(int i = 0; i < 3; ++i){ m_CurrentStateInfo[i] = m_Animator.GetCurrentAnimatorStateInfo(i); /* m_NextStateInfo[i] = m_Animator.GetNextAnimatorStateInfo(i); m_IsAnimatorTransitioning[i] = m_Animator.IsInTransition(i); */ } } bool IsStateLocomotion(){ bool isState = m_CurrentStateInfo[0].fullPathHash == hashStateLocomotion; return isState; } bool IsStateAttack(){ bool isState = m_CurrentStateInfo[1].fullPathHash == hashStateAttack_1; //AnimatorStateInfo[]のIndexをレイヤーと同じ番号にすること return isState; }
今回はAnimator.GetCurrentAnimatorStateInfoのみを用いたが、他にもAnimator.GetNextAnimatorStateInfoやAnimator.IsInTransitionを使って比較できたりもする
Unity - Scripting API: Animator.StringToHash
Unity - Scripting API: Animator.GetCurrentAnimatorStateInfo
【Unity】アクションゲームで使える攻撃判定を作る
やりたいこと
任意の座標・大きさの範囲内にあるコライダーを取得したい
結論
Physics.OverlapBoxNonAlloc
Physics.OverlapSphereNonAlloc
Physics.OverlapCapsuleNonAlloc
を使う
解説(?)
3Dで攻撃判定を作るときBoxColliderやCapsuleColliderを使う手段もありますが、攻撃判定を一度に複数用意したい・判定の大きさを変えたいとなった際ちょっと不便です
また、Colliderは触れたものすべてをメモリに溜め込むため(Layerである程度ふるいにかけることはできますが)一度の判定で膨大な数のオブジェクトを取得してしまうこともあります
対してPhysics.Overlap~NonAllocは個数や大きさ、座標を簡単に変えられたり、決めた要素数以上のオブジェクトを取得しない仕組みになっているため、GCの発生を抑えることができます
以下サンプル