Unity 中的座標系統Coordinate systems in Unity

Windows Mixed Reality 透過房間規模的應用程式,支援橫跨各種 體驗規模的應用程式,從僅限方向和已安置規模的應用程式。Windows Mixed Reality supports apps across a wide range of experience scales, from orientation-only and seated-scale apps up through room-scale apps. 在 HoloLens 上,您可以進一步建立全球規模的應用程式,讓使用者超越5個計量,探索整個大樓的整個樓層。On HoloLens, you can go further and build world-scale apps that let users walk beyond 5 meters, exploring an entire floor of a building and beyond.

在 Unity 中打造混合現實體驗的第一個步驟,是決定您的應用程式將設為目標的 體驗規模Your first step in building a mixed reality experience in Unity is to determine which experience scale your app will target.

打造僅限方向或內部規模的體驗Building an orientation-only or seated-scale experience

命名空間: UnityEngine. XRNamespace: UnityEngine.XR
類型: XRDeviceType: XRDevice

若要建立 僅限方向 或內部 規模的體驗,您必須將 Unity 設定為「固定追蹤空間」類型。To build an orientation-only or seated-scale experience, you need to set Unity to the Stationary tracking space type. 固定追蹤空間會設定 Unity 的全局座標系統,以追蹤 固定的參考框架Stationary tracking space sets Unity's world coordinate system to track the stationary frame of reference. 在「固定追蹤」模式中,放在「相機」預設位置前方之編輯器中的內容 (轉寄是-Z) 將會在應用程式啟動時出現在使用者前面。In the Stationary tracking mode, content placed in the editor just in front of the camera's default location (forward is -Z) will appear in front of the user when the app launches.

XRDevice.SetTrackingSpaceType(TrackingSpaceType.Stationary);

命名空間: UnityEngine. XRNamespace: UnityEngine.XR
類型: InputTrackingType: InputTracking

若要取得純 方向的體驗 (例如360度的影片檢視器) (其中的位置標頭更新會使假像) 損毀,您可以接著設定 XR。InputTracking. disablePositionalTracking 至 true:For a pure orientation-only experience such as a 360-degree video viewer (where positional head updates would ruin the illusion), you can then set XR.InputTracking.disablePositionalTracking to true:

InputTracking.disablePositionalTracking = true;

針對內部 規模的體驗,讓使用者稍後 recenter 已安裝的來源,您可以呼叫 XR。InputTracking. Recenter 方法:For a seated-scale experience, to let the user later recenter the seated origin, you can call the XR.InputTracking.Recenter method:

InputTracking.Recenter();

打造大規模或房間規模的體驗Building a standing-scale or room-scale experience

命名空間: UnityEngine. XRNamespace: UnityEngine.XR
類型: XRDeviceType: XRDevice

若要獲得 大規模房間規模的體驗,您必須將內容放在地面的相對位置。For a standing-scale or room-scale experience, you'll need to place content relative to the floor. 您可以使用 空間階段(代表使用者定義的樓層層級來源和選擇性的空間界限),在第一次執行期間設定使用者的樓層。You reason about the user's floor using the spatial stage, which represents the user's defined floor-level origin and optional room boundary, set up during first run.

為了確保 Unity 在地面層級的全局座標系統運作,您可以設定並測試 Unity 是否使用 RoomScale 追蹤空間類型:To ensure that Unity is operating with its world coordinate system at floor-level, you can set and test that Unity is using the RoomScale tracking space type:

if (XRDevice.SetTrackingSpaceType(TrackingSpaceType.RoomScale))
{
    // RoomScale mode was set successfully.  App can now assume that y=0 in Unity world coordinate represents the floor.
}
else
{
    // RoomScale mode was not set successfully.  App cannot make assumptions about where the floor plane is.
}
  • 如果 SetTrackingSpaceType 傳回 true,表示 Unity 已成功切換其全局座標系統,以追蹤 參考的階段框架If SetTrackingSpaceType returns true, Unity has successfully switched its world coordinate system to track the stage frame of reference.
  • 如果 SetTrackingSpaceType 傳回 false,則 Unity 無法切換至參考的階段框架,可能是因為使用者未在其環境中設定 floor。If SetTrackingSpaceType returns false, Unity was unable to switch to the stage frame of reference, likely because the user has not set up a floor in their environment. 雖然錯誤傳回值並不常見,但如果階段是在不同的房間內設定的,而且裝置會移至目前的房間,而沒有使用者設定新的階段,就可能發生此情況。While a false return value isn't common, it can happen if the stage is set up in a different room and the device is moved to the current room without the user setting up a new stage.

一旦您的應用程式成功設定 RoomScale 追蹤空間類型,放在 y = 0 平面上的內容就會出現在樓層上。Once your app successfully sets the RoomScale tracking space type, content placed on the y=0 plane will appear on the floor. 0、0、0的原點將是使用者在房間設定期間勇敢面對考驗的特定位置,而-Z 代表在安裝期間所面對的順向方向。The origin at 0, 0, 0 will be the specific place on the floor where the user stood during room setup, with -Z representing the forward direction they were facing during setup.

命名空間: UnityEngine。 XRNamespace: UnityEngine.Experimental.XR
類型: 界限Type: Boundary

在腳本中,您可以呼叫 UnityEngine 的 TryGetGeometry 方法,以取得界限多邊形,並指定 TrackedArea 的界限類型。In script code, you can then call the TryGetGeometry method on the UnityEngine.Experimental.XR.Boundary type to get a boundary polygon, specifying a boundary type of TrackedArea. 如果使用者定義了界限, (您取得頂點) 的清單,就可以安全地將 房間規模的體驗 提供給使用者,讓他們可以在您建立的場景周圍四處進行。If the user defined a boundary (you get back a list of vertices), it's safe to deliver a room-scale experience to the user, where they can walk around the scene you create.

注意

當使用者進行方法時,系統會自動呈現界限。The system will automatically render the boundary when the user approaches it. 您的應用程式不需要使用此多邊形來呈現界限本身。Your app doesn't need to use this polygon to render the boundary itself. 不過,您可以選擇使用此界限多邊形來配置場景物件,以確保使用者可以在不 teleporting 的情況下,實際觸及這些物件:However, you may choose to lay out your scene objects using this boundary polygon, to ensure the user can physically reach those objects without teleporting:

var vertices = new List<Vector3>();
if (UnityEngine.Experimental.XR.Boundary.TryGetGeometry(vertices, Boundary.Type.TrackedArea))
{
    // Lay out your app's content within the boundary polygon, to ensure that users can reach it without teleporting.
}

打造全球規模的體驗Building a world-scale experience

命名空間: UnityEngine. XRNamespace: UnityEngine.XR.WSA
類型: WorldAnchorType: WorldAnchor

若要在 HoloLens 上讓使用者穿梭超過5個度量的真實 世界規模體驗 ,您將需要新的技術,而不是用於會議室規模的體驗。For true world-scale experiences on HoloLens that let users wander beyond 5 meters, you'll need new techniques beyond those used for room-scale experiences. 您將使用的一項重要技巧是建立 空間錨點 ,以在實體世界中精確地鎖定大量的全像位置,而不論使用者漫遊的程度為何,然後 在後續的會話中再次找出這些影像One key technique you'll use is to create a spatial anchor to lock a cluster of holograms precisely in place in the physical world, no matter how far the user has roamed, and then find those holograms again in later sessions.

在 Unity 中,您可以藉由將 WorldAnchor Unity 元件新增至 GameObject 來建立空間錨點。In Unity, you create a spatial anchor by adding the WorldAnchor Unity component to a GameObject.

新增世界錨點Adding a World Anchor

若要新增世界錨點,請 使用您要錨定到真實世界的轉換,在遊戲物件上呼叫 AddComponent ( # A1。To add a world anchor, call AddComponent() on the game object with the transform you want to anchor in the real world.

WorldAnchor anchor = gameObject.AddComponent<WorldAnchor>();

這樣就完成了!That's it! 此遊戲物件現在會錨定在實體世界中的目前位置,您可能會看到其 Unity 全局座標在一段時間後會稍微調整,以確保實體對齊。This game object will now be anchored to its current location in the physical world - you may see its Unity world coordinates adjust slightly over time to ensure that physical alignment. 使用 持續 性,在未來的應用程式會話中再次尋找此錨定的位置。Use persistence to find this anchored location again in a future app session.

移除世界錨點Removing a World Anchor

如果您不想再將 GameObject 鎖定到實體世界位置,也不想要將它移到此框架,您可以直接在世界錨點元件上呼叫摧毀。If you no longer want the GameObject locked to a physical world location and don't intend on moving it this frame, then you can just call Destroy on the World Anchor component.

Destroy(gameObject.GetComponent<WorldAnchor>());

如果您想要將 GameObject 移到這個畫面格,您必須改為呼叫 DestroyImmediate。If you want to move the GameObject this frame, you need to call DestroyImmediate instead.

DestroyImmediate(gameObject.GetComponent<WorldAnchor>());

移動世界錨定的 GameObjectMoving a World Anchored GameObject

當世界錨點在其上時,無法移動 GameObject。GameObject's cannot be moved while a World Anchor is on it. 如果您需要將 GameObject 移到此框架,您需要:If you need to move the GameObject this frame, you need to:

  1. DestroyImmediate 世界錨點元件DestroyImmediate the World Anchor component
  2. 移動 GameObjectMove the GameObject
  3. 將新的世界錨點元件新增至 GameObject。Add a new World Anchor component to the GameObject.
DestroyImmediate(gameObject.GetComponent<WorldAnchor>());
gameObject.transform.position = new Vector3(0, 0, 2);
WorldAnchor anchor = gameObject.AddComponent<WorldAnchor>();

處理 Locatability 變更Handling Locatability Changes

在某個時間點,實體世界可能無法找出 WorldAnchor。A WorldAnchor may not be locatable in the physical world at a point in time. 如果發生這種情況,Unity 將不會更新錨定物件的轉換。If that occurs, Unity won't be updating the transform of the anchored object. 當應用程式正在執行時,這也可能會變更。This also can change while an app is running. 無法處理 locatability 中的變更,會導致物件不會出現在世界中正確的實體位置。Failure to handle the change in locatability will cause the object to not appear in the correct physical location in the world.

若要收到有關 locatability 變更的通知:To be notified about locatability changes:

  1. 訂閱 OnTrackingChanged 事件Subscribe to the OnTrackingChanged event
  2. 處理事件Handle the event

只要基礎空間錨點在所可定位的狀態與未被定位之間變更時,就會呼叫 OnTrackingChanged 事件。The OnTrackingChanged event will be called whenever the underlying spatial anchor changes between a state of being locatable vs. not being locatable.

anchor.OnTrackingChanged += Anchor_OnTrackingChanged;

然後處理事件:Then handle the event:

private void Anchor_OnTrackingChanged(WorldAnchor self, bool located)
{
    // This simply activates/deactivates this object and all children when tracking changes
    self.gameObject.SetActiveRecursively(located);
}

有時會立即找到錨點。Sometimes anchors are located immediately. 在此情況下,當 AddComponent ( # A1 傳回時,錨點的這個 isLocated 屬性會設定為 true In this case, this isLocated property of the anchor will be set to true when AddComponent() returns. 因此,將不會觸發 OnTrackingChanged 事件。As a result, the OnTrackingChanged event won't be triggered. 清除模式是在附加錨點之後,以初始 IsLocated 狀態呼叫您的 OnTrackingChanged 處理常式。A clean pattern would be to call your OnTrackingChanged handler with the initial IsLocated state after attaching an anchor.

Anchor_OnTrackingChanged(anchor, anchor.isLocated);

跨裝置共用錨點Sharing anchors across devices

使用 Azure 空間錨點 ,從本機 WorldAnchor 建立持久的雲端錨點,讓您的應用程式可在多個 HoloLens、IOS 和 Android 裝置上找到。Use Azure Spatial Anchors to create a durable cloud anchor from a local WorldAnchor, which your app can then locate across multiple HoloLens, iOS and Android devices. 藉由在多個裝置上共用一般空間錨點,每個使用者都可以在相同的實體位置中看到相對於該錨點轉譯的內容。By sharing a common spatial anchor across multiple devices, each user can see content rendered relative to that anchor in the same physical location. 這可提供即時共用體驗。This allows for real-time shared experiences.

若要開始在 Unity 中建立共用體驗,請嘗試5分鐘的 Azure 空間錨點 Unity 快速入門To get started building shared experiences in Unity, try out the 5-minute Azure Spatial Anchors Unity quickstarts.

在您啟動並執行 Azure 空間錨點之後,您可以 在 Unity 中建立及尋找錨點Once you're up and running with Azure Spatial Anchors, you can then create and locate anchors in Unity.

下一個開發檢查點Next Development Checkpoint

如果您正在遵循我們所配置的 Unity 開發檢查點旅程,您將會在探索混合現實核心構成要素。If you're following the Unity development checkpoint journey we've laid out, you're in the midst of exploring the Mixed Reality core building blocks. 接下來,您可以繼續進行下一個建置組塊:From here, you can continue to the next building block:

或者,直接跳到混合實境平台功能和 API 的主題:Or jump to Mixed Reality platform capabilities and APIs:

您可以隨時回到 Unity 開發檢查點You can always go back to the Unity development checkpoints at any time.

另請參閱See Also