🐙

XR Interaction Toolkitで、オブジェクトを持った時に動けなくなる(向きが変えられなくなる)問題の解決

2022/08/15に公開

環境

問題

  • オブジェクトを持った状態で、方向を変えられない(Snap Turn等が効かない)、移動できない(Continuous Moveが効かない)

原因

  • XROrigin > Camera Offset > Left HandにアタッチしたAction Based Controller Manager(XRI Examplesから利用したスクリプト)が原因
  • Action Based Controller Managerは、1人称移動とテレポート移動の切り替えを行ってくれるので導入している

解決策

  • ActionBasedControllerManager.csの問題個所を2行削除することで解決(自分のバージョンでは472,3行目)
    void OnExitSelectState(StateId nextStateId)
    {
        // Change controller and disable actions depending on the next state
        switch (nextStateId)
        {
            case StateId.None:
                break;
            case StateId.Select:
                break;
            case StateId.Teleport:
                DisableAction(m_Turn);
                DisableAction(m_Move);
                SetBaseController(false);
                break;
            case StateId.Interact:
                // DisableAction(m_Turn); ←ここ
                // DisableAction(m_Move); ← ここ
                break;
            default:
                Debug.Assert(false, $"Unhandled case when exiting Select to {nextStateId}.");
                break;
        }
    }

該当箇所のメソッドが呼ばれるタイミングについて

   void OnEnterSelectState(StateId previousStateId)
    {
        // Change controller and enable actions depending on the previous state
        switch (previousStateId)
        {
            case StateId.None:
                Debug.Log("OnEnterSelectState: PreviousID = Noneが呼ばれた");
                // Enable transitions to Teleport state 
                EnableAction(m_TeleportModeActivate);
                EnableAction(m_TeleportModeCancel);

                // Enable turn and move actions
                EnableAction(m_Turn);
                EnableAction(m_Move);

                // Enable base controller components
                SetBaseController(true);
                break;
            case StateId.Select:
                Debug.Log("OnEnterSelectState: PreviousID = Selectが呼ばれた");
                break;
            case StateId.Teleport:
                Debug.Log("OnEnterSelectState: PreviousID = Teleportが呼ばれた");
                EnableAction(m_Turn);
                EnableAction(m_Move);
                SetBaseController(true);
                break;
            case StateId.Interact:
                Debug.Log("OnEnterSelectState: PreviousID = Interactが呼ばれた");
                EnableAction(m_Turn);
                EnableAction(m_Move);
                break;
            default:
                Debug.Assert(false, $"Unhandled case when entering Select from {previousStateId}.");
                break;
        }
    }

    void OnExitSelectState(StateId nextStateId)
    {
        // Change controller and disable actions depending on the next state
        switch (nextStateId)
        {
            case StateId.None:
                Debug.Log("OnExitSelectState: NextID = Noneが呼ばれた");
                break;
            case StateId.Select:
                Debug.Log("OnExitSelectState: NextID = Selectが呼ばれた");
                break;
            case StateId.Teleport:
                Debug.Log("OnExitSelectState: NextID = Teleportが呼ばれた");
                DisableAction(m_Turn);
                DisableAction(m_Move);
                SetBaseController(false);
                break;
            case StateId.Interact:
                Debug.Log("OnExitSelectState: NextID = Interactが呼ばれた");
                //DisableAction(m_Turn);
                //DisableAction(m_Move);
                break;
            default:
                Debug.Assert(false, $"Unhandled case when exiting Select to {nextStateId}.");
                break;
        }
    }
  • 「Sceneを再生 → オブジェクトを持つ → 10秒間保持 → オブジェクトを離す」としたときのログ
  • ここから考察するに、
    • ものを持てる状態になったとき(何も持っていないとき)=> OnEnterSelectEventが呼ばれる
    • ものを持った状態になったとき => OnExitSelectEventが呼ばれる

Discussion

ログインするとコメントできます