共用方式為


規劃求解 - MRTK3

規劃求解主

規劃求解器是一種元件,可協助根據預先定義的演算法來計算物件的位置和方向。 範例:將物件放在使用者注視光線傳播交集的表面上。

規劃求解系統會決定性地定義這些轉換計算的作業順序,因為沒有可靠的方法可以指定給 Unity 元件的更新順序。

規劃求解會提供一系列的行為,將物件附加至其他對象或系統。 另一個範例是沿著標記的物件,會根據相機將滑鼠停留在使用者的前面。 規劃求解也可以附加至控制器和 物件,使對象標記沿著控制器。 所有求解器都可以安全地堆疊,例如,標記沿著行為加上表面磁力加上動力。

如何使用

規劃求解系統包含三種類別的腳稿:

  • Solver:所有求解器衍生的抽象基類。 它提供狀態追蹤、平滑參數和實作、自動規劃求解系統整合,以及更新順序。
  • SolverHandler:針對 (範例設定參考對象追蹤:主相機轉換、手部光線等 ) 、處理求解器元件的收集,並以適當的順序執行更新。

第三個類別是求解器本身。 下列求解器提供基本行為的建置組塊:

  • Orbital:鎖定至指定的位置,並從參考的物件位移。
  • ConstantViewSize:縮放以維護相對於參考物件檢視的常數大小。
  • RadialView:將物件保留在所參考物件所轉換的檢視錐內。
  • Follow:將 物件保留在所參考物件的一組用戶定義界限內。
  • InBetween:將物件保留在兩個追蹤對象之間。
  • SurfaceMagnetism:將光線轉換成世界的表面,並將物件對齊該表面。
  • DirectionalIndicator:決定物件的位置和方向做為方向指示器。 從 SolverHandler 追蹤目標的參考點開始,此指標會朝向提供的 DirectionalTarget 方向。
  • Momentum:套用加速/速度/摩擦,以模擬其他求解器/元件移動之對象的動力和彈跳。
  • HandConstraint:條件約束物件,可在不會與 GameObject 與手交集的區域中追蹤手部。 適用於手部限制的互動式內容,例如功能表等。此解算器是要與 搭配 XRNode使用。
  • HandConstraintPalmUp:衍生自 HandConstraint,但包含邏輯,可在啟動之前測試手掌是否正朝向使用者。 此求解器只適用於 XRNode 控制器,其行為就如同其基類與其他控制器類型一樣。
  • Overlap:與追蹤的 物件重疊。

若要使用規劃求解系統,請將上面所列的其中一個元件新增至 GameObject。 因為所有規劃求解都需要 SolverHandler,所以 Unity 會自動建立一個。

注意事項

您可以在 SolverExamples.scene 檔案中找到如何使用規劃求解系統的範例。

如何變更追蹤參考

元件的 SolverHandlerTracked Target Type 屬性會定義所有求解器將用來計算其演算法的參考點。 例如,具有簡單SurfaceMagnetism元件的 Head 實值類型會導致光線從頭部和用戶注視的方向轉換,以解決所叫用的表面。 屬性的潛在值 TrackedTargetType 為:

  • *頭部:參考點是主相機的轉換
  • ControllerRay:參考點是 LinePointer 控制器 (上的轉換,也就是運動控制器或手部控制器上的指標原點) 指向線條光線的方向
    • 使用 屬性 TrackedHandedness 來選取手 (喜好設定,也就是 Left、Right、Both)
  • HandJoint:參考點是特定手部接合的轉換
    • 使用 屬性 TrackedHandedness 來選取手 (喜好設定,也就是 Left、Right、Both)
    • TrackedHandJoint使用屬性來判斷要使用的聯合轉換
  • CustomOverride:來自指派之 的參考點 TransformOverride

注意事項

針對 ControllerRayHandJoint 類型,規劃求解處理程式會先嘗試提供左控制器/手部轉換,如果前者無法使用,則為右側,否則除非 TrackedHandedness 屬性另有指定。

重要事項

大部分的求解器都會使用 所提供之追蹤轉換目標的 SolverHandler正向向量。 使用 手部接合 追蹤目標類型時,手掌介面的正向向量可能會指向手指,而不是透過手掌。 這取決於提供手部聯合數據的平臺。 針對輸入模擬和 Windows Mixed Reality,向上向量會透過手掌向上 (換句話說,綠色向量是向上的,藍色向量是正向) 。

若要克服此問題,請將 上的 SolverHandler[其他旋轉] 屬性更新為 <90, 0, 0>。 這可確保提供給求解器的正向向量會透過手掌指向,並從手部向外指向。

或者,使用 控制器 Ray 追蹤目標類型,以取得以手指針的類似行為。

如何鏈鏈規劃求解器

您可以將多個 Solver 元件新增至相同的 GameObject,因而鏈結其演算法。 元件 SolverHandler 會處理更新相同 GameObject 上的所有求解器。 根據預設, SolverHandler Start 上的呼叫 GetComponents<Solver>() 會以它們出現在偵測器中的順序傳回規劃求解。

此外,將 [已更新的鏈接轉換 ] 屬性設定為 true 會指示 Solver 將計算位置、方向和縮放儲存至所有規劃求解 (可存取的中繼變數, GoalPosition 也就是) 。 當為 false 時, Solver 會直接更新 GameObject 的轉換。 藉由將轉換屬性儲存至中繼位置,其他規劃求解器可以從中繼變數開始執行其計算。 這是因為 Unity 不允許更新 gameObject.transform,以堆疊在相同的框架內。

注意事項

開發人員可以直接設定 SolverHandler.Solvers 屬性,以修改規劃求解的執行順序。

如何建立新的求解器

所有求解器都必須繼承自抽象基類 。 Solver 規劃求解擴充功能的主要需求包括覆寫 SolverUpdate 方法。 在此方法中,開發人員應該將繼承 GoalPosition的、 GoalRotationGoalScale 屬性更新為所需的值。 此外,利用 作為取用者所需的參考框架也很有價值 SolverHandler.TransformTarget

下列提供的程式代碼提供名為 InFront 的新規劃求解元件範例,該元件會將附加的物件放在 前面 SolverHandler.TransformTarget2 公尺。 取用者會將 設定 SolverHandler.TrackedTargetTypeHead,然後 SolverHandler.TransformTarget 會是相機轉換,因此此規劃求解會將附加的 GameObject 放在使用者注視的每個畫面前 2 公尺。

/// <summary>
/// InFront solver positions an object 2m in front of the tracked transform target
/// </summary>
public class InFront : Solver
{
    ...

    public override void SolverUpdate()
    {
        if (SolverHandler != null && SolverHandler.TransformTarget != null)
        {
            var target = SolverHandler.TransformTarget;
            GoalPosition = target.position + target.forward * 2.0f;
        }
    }
}

規劃求解實作指南

一般求解器屬性

每個規劃求解元件都有一組核心相同的屬性,可控制核心規劃求解行為。

如果已啟用 Smoothing ,規劃求解會隨著時間逐漸將 GameObject 的轉換更新為導出值。 每個轉換元件的 LerpTime 屬性都會決定這項變更的速度。 例如,較高的 MoveLerpTime 值會導致畫面之間的移動速度變慢。

如果已啟用 MaintainScale ,規劃求解會利用GameObject的預設本機規模。

軌道的

類別 Orbital 是沿著標記的元件,其行為類似於太陽能系統中的行星。 此規劃求解會確保附加的 GameObject 繞著追蹤的轉換運行。 因此,如果的 [追蹤目標類型SolverHandler] 設定為 Head,則 GameObject 會繞著套用固定位移的使用者頭部周遊。

開發人員可以修改此固定位移,以將功能表或其他場景元件保留在使用者的眼球層級或等級等。 這可藉由變更 Local OffsetWorld Offset 屬性來完成。 Orientation Type 屬性會決定套用至物件的旋轉,如果它應該維持其原始旋轉,或一律面對相機或臉部任何正在驅動其位置的轉換。

RadialView

RadialView是另一個標記一起元件,可將 GameObject 的特定部分保留在用戶檢視範圍內。

[最小 & 檢視度數] 屬性會決定 GameObject 的一部分必須一律在檢視中。

Min & Max Distance 屬性會決定 GameObject 應該與使用者保持的距離。 例如,以 1 公尺 的最小距離 朝向 GameObject 移動,會將 GameObject 推開,以確保它永遠不會接近使用者 1 公尺。

一般而言, RadialView 會與設定為 Head的追蹤目標類型搭配使用,讓元件遵循使用者的注視。 不過,此元件可以保留在任何追蹤目標類型的「檢視」中。

跟進

類別會 Follow 將專案置於追蹤目標前面,相對於其本機正向軸。 元素可以鬆散地受限 (也稱為「標記一起」) ,因此在追蹤的目標超出使用者定義的界限之前,不會跟著做。

其運作方式類似於RadialView規劃求解,具有其他控件來管理 最大水準 & 垂直檢視度 和改變物件 方向的機制。

InBetween

類別 InBetween 會在兩個轉換之間保留附加的 GameObject。 GameObject 自己的 SolverHandler追蹤目標類型InBetween 元件的第 二個追蹤目標類型 屬性會定義這兩個轉換端點。 一般而言,這兩種類型都會設定為 CustomOverride ,而產生的 SolverHandler.TransformOverrideInBetween.SecondTransformOverride 值會設定為兩個追蹤的端點。

元件InBetween會在運行時間根據第二個追蹤目標類型和第二轉換覆寫屬性建立另一個SolverHandler元件。

在兩個轉換之間的行中, PartwayOffset 會定義物件的放置位置,其中 0.5 為中間,第一個轉換為 1.0,第二個轉換為 0.0。

SurfaceMagnetism

SurfaceMagnetism 運作方式是針對一組 SurfaceMask 的集合執行光線廣播,並將 GameObject 放在該接觸點。

Surface Normal Offset 會將 GameObject 放在距離表面以公尺為單位的一定距離,方向為介面上的一般值。

相反地, Surface Ray Offset 會將 GameObject 放在距離表面以公尺為單位的設定距離,但會以相反方向執行的光線傳播。 因此,如果光線廣播是使用者的注視,GameObject 會沿著從表面的點擊點到相機的線條往近移動。

方向模式會決定要套用的旋轉類型,與介面上的一般相關。

  • - 不套用旋轉
  • TrackedTarget - 物件將面對驅動光線傳播的追蹤轉換
  • SurfaceNormal - 對象會根據介面上的一般點對齊
  • Blended - 對象會根據介面上的一般點對齊,並根據面向的追蹤轉換來對齊。

若要強制關聯的 GameObject 在 None 以外的任何模式中保持垂直,請啟用 保持垂直方向

注意事項

當 [方向模式] 設定為 [混合] 時,請使用 Orientation Blend 屬性來控制旋轉因數之間的平衡。 0.0 的值將具有完全由 TrackedTarget 模式驅動的方向,而 1.0 的值將完全由 SurfaceNormal 驅動方向。

Overlap

Overlap是簡單的求解器,可將對象的轉換保留在與轉換目標相同的位置和旋轉SolverHandler's位置。

判斷可以叫用的表面

將元件新 SurfaceMagnetism 增至 GameObject 時,如果有任何碰撞器,請務必考慮 GameObject 及其子系的圖層。 元件的運作方式是執行各種光線傳播,以判斷要對它本身「磁化」的表面。 假設規劃求解工具 GameObject 在 屬性中MagneticSurfacesSurfaceMagnetism所列的其中一個層次上有一個碰撞器。 在此情況下,光線傳播可能會自行點擊,導致 GameObject 附加至它自己的碰撞器點。 將主要 GameObject 和所有子系設定為 Ignore Ray 轉換 層,或適當地修改 MagneticSurfaces LayerMask 數位,即可避免這種奇數行為。

相反地, SurfaceMagnetism GameObject 不會與屬性中 MagneticSurfaces 未列出之圖層上的表面相衝突。 建議您將所有所需的表面放在專用的圖層 (也就是 Surfaces) ,並將 屬性設定 MagneticSurfaces 為僅此圖層。 使用 預設 值或 所有 專案可能會導致UI元件或數據指針對求解器造成貢獻。

最後,光線傳播會忽略比 MaxRaycastDistance 屬性設定還要遠的 SurfaceMagnetism 表面。

DirectionalIndicator

類別 DirectionalIndicator 是沿著標記的元件,可將本身導向至所需空間點的方向。 當 的 [追蹤目標類型 ] 設定為 時, SolverHandler 最常使用它 Head。 以此方式,具有求解器的 DirectionalIndicator UX元件會引導使用者查看所需的空間點。 此點取決於 方向目標 屬性。

如果用戶可檢視方向目標,或是在 中 SolverHandler設定任何參考框架,則此規劃求解會停用其下的所有 Renderer 元件。 如果無法檢視,則會在指標上啟用所有專案。

指標的大小會縮小使用者在FOV中擷取 方向目標 的距離。

  • 最小指標小數位數 - 指針對象的最小尺規

  • 最大指標尺規 - 指針對象的最大尺規

  • 可見度縮放比例 - 增加或減少FOV的乘數,決定 方向目標 點是否可檢視

  • 檢視位移 - 從參考 (的視點來看,相機可能) ,而在指標方向中,這個屬性會定義物件距離檢視區中央的距離。

方向指示器範例場景 (Assets/MRTK/Examples/Demos/Solvers/Scene/DirectionalIndicatorSolverExample.unity)

使用 HandConstraint 和 HandConstraintPalmUp 的手部功能表

行為 HandConstraint 會提供一個求解器,將追蹤物件限制為手部限制內容的安全區域 (例如手部 UI、功能表等。) 安全區域會被視為與手部不交集的區域。 也包含名為 HandConstraintPalmUpHandConstraint衍生類別,以示範當手掌面對使用者時,啟動規劃求解追蹤對象的常見行為。

如需使用手部條件約束求解器建立手部功能表的範例,請參閱手部功能表檔。