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. 在静止跟踪模式下,显示在面板默认位置之前的编辑器中的内容 (向前) 在应用启动时将显示在用户的前面。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 无法切换到引用的阶段框架,原因可能是用户尚未在其环境中设置楼层。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