只要是 Windows 10 的作業系統都可執行 Universal Windows Platform 開發的 Apps,當然包括 Xbox one。
本篇介紹移植 App 到 Xbox 時需要調整的地方。
開發 Xbox 上的 App 有幾個重點:
- Getting started with UWP app development on Xbox One 先參考這篇把環境設定好
- 預設 deploy 到 Xbox 上的 Apps 有一個 游標 讓用戶像網頁一樣操作 Apps (Mouse mode is now enabled by default)
- How to disable mouse mode 關閉預設使用 游標 控制畫面,因爲使用搖桿操作比較符合用戶的體驗
- Gamepad 與 remote control 是主要的操作工具, focus 的控制非常重要,避免用戶迷失 (XY focus navigation)
- 電視的 screen size 與比例與電腦/手機上有很大的不同 (television 10-foot experience)
- 參考 Focus visual 的做法,在 Xbox 運作時調整 XAML 讓每個 Item 被 focus 時能有比較明顯的呈現,避免用戶的迷失。
- 處理 TV-safe area 避免畫面被切掉,與 tv-safe color 避免某些顔色無法顯示故不要使用太極端的顔色
- UWP app 會自動 scaling 確保在任何 devices 都能正常顯示,在 Xbox 自動被 scaling 到 200%,
如果想自定調整顯示範圍改用實際尺寸計算,可以參考 How to turn off scaling 與 Effective pixels and scaling - UWP on Xbox 記憶體用量分配: foreground 最大 1G; background 最大 128 MB,可參考 System resources for UWP apps and games on Xbox One
- 其他問題可以參考 Frequently asked questions
根據 Designing for Xbox and TV 的説明,做在沙發使用 gamepad 或 remote 去控制 TV,這個行爲被稱爲 10-foot experience,
因爲通常沙發跟電視的距離約 10 feet;而 2-foot experience 説明的是 PC。 開發 Xbox 的應用要把握這個距離原則,做到幾個重點:
- Simple
解析度與距離的關係,用戶很難處理畫面太多的資訊,應該保持乾净的設計,減少到最簡單的畫面元件,
可能畫面會接近在 Mobile 的内容而不像 Desktop 這麽多元 - Coherent
App 設計應該簡單容易操作,是 focus 清楚,移動的距離,階層,路徑都是一致且最少步驟就能完成想做的事情。
- Gamepad and remote control
重要的步驟,決定用戶如何操作 gamepad 或 remote 使用 App 的功能又不會不方便,
參考 XY focus navigation and interaction 與 Mouse mode 調整操作元件的方式。
開始前建議先使用 keyboard 操作 App 找到那些畫面或是元件的問題,再開始調整。 上圖是 gamepad 與 remote 按鈕的差別與介紹,按鈕的使用建議優先支援共用的會比較好,例如:X/Y/A(select)/B(back) buttons 與 menu/views button。
按下 B(back) button 時,可利用 SystemNavigationManager.BackRequested 直接控制。
gamepad 的按鈕上也額外支援一些特定的控制項,例如:ScrollViewer 的就可以用 left/right trigger 快速垂直 scroll,可參考 Gamepad and remote control。 - XY focus navigation and interaction
gamepad 或 remote 只支援移動到擁有 IsTabStop = true 與 Visibility = visible 的控制項,可參考 Keyboard interactions。
同理如果支援 keyboard 操作的更完整,您的 App 將會變的更方便。
利用 FocusManager.GetFocusedElement 得知現在那個控制項被 focus,用於瞭解目前 focus 到底跑到哪裏。page.GotFocus += (object sender, RoutedEventArgs e) => { FrameworkElement focus = FocusManager.GetFocusedElement() as FrameworkElement; if (focus != null) { Debug.WriteLine("got focus: " + focus.Name + " (" + focus.GetType().ToString() + ")"); } };
- IsTapStop 或是 Visibility 設定錯誤
- 被 focus 的控制項實際上比看到的還要大,因爲 XY navigation 使用的是 ActualWidth/ActualHeight
- 不支援重曡的控制項被 focus,一次只能 focus 一個控制項
如果 XY navigation 走向的位置不符合預期的話就要覆寫控制項的 XY navigation,强迫給定每個控制項的位置關係,可以參考 Overriding the default navigation。
如果覆寫 XY navigation 不需要重覆指定,例如: Button1.XYFocusLeft = Button2 而在 Button2.XYFocusRight = Button1。
如果覆寫 XY navigation 控制項内的子控制項一樣會承接這個設定。
如果 XY navigation 是正常的,但是 focus visual 在 focus 時沒有顯示,可以參考下面的排除方式:- re-template 控制項,而且拿掉 focus virtual。搭配 UseSystemFocusVisuals="True" 或是手動加入 focus visual 來確認
- 利用 Focus(FocusState.Pointer) 移動 focus 確定控制項有被 focus。通常會用 Focus(FocusState.Programmatic)。
CommandBar 與 ContextFlyou:ContextFlyout 可以處理 gamepad 上的 menu 按鈕來完成;
CommandBar 在 Xbox 上的操作不是這麽容易,建議改用 ContextFlyou 或是其他元件代替,可參考 Problem: UI elements located after long scrolling list/grid。 - Mouse mode
App.xaml.cs 的建構子加入 disable mouse mode:
public App() { this.InitializeComponent(); this.Suspending += OnSuspending; if (IsXbox()) { Application.Current.RequiresPointerMode = ApplicationRequiresPointerMode.WhenRequested; } } static string deviceFamily; public static bool IsXbox() { if (deviceFamily == null) { deviceFamily = Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily; } return deviceFamily == "Windows.Xbox"; }
<Page> <Grid> <MapControl IsEngagementRequired="true" RequiresPointer="WhenEngaged"/> </Grid> </Page>
不希望有 mouse mode 出現,可以在該 Page 設定 RequiresPointer="Never"。 - Focus visual
focus visual 是周圍邊框表示目前控制項被關注,幫用戶簡單的知道目前位置與瀏覽的方向。
雖然把 focus visual 的控制設定好可以跨所有裝置,但是在 10-foot experience (電視或更大的屏幕)還是有些不同。
因爲畫面太大用戶很難一次看到全部的範圍,因此在 focus visual 需要更明顯與清楚的顯示,避免用戶做視覺的搜索。
電視設計不像鍵盤,建議預設就幫用戶關注一個控制項目,讓用戶方便找到瀏覽方向。 整理幾個重點:- Initial focus visual placement
當 App 被啓動或是進去某個 Page,請幫用戶自動 focus 到畫面中你預期開始操作的位置。
例如:photo app 預設選擇第一張圖片;music app 預設選擇第一首歌曲。
也可以預設將焦點放在左上角區域,因爲大部分的 App 操作流程都是從左上角開始。 - Making focus clearly visible
建議屏幕是始終有一個焦點,用戶就能快速找到關注的地方。但是如果畫面是一個 full screen 的 video / photo / documents 就不一定適合。
- Customizing the focus visual
- Light dismiss overlay
爲了使用戶注意當前用 gamepad 或是 remote control 操作的 UI 元素,UWP 自動添加了一個 Smoke layer 讓彈跳式 UI 在顯示時自動遮住背後的内容,
讓用戶專注在彈跳出來的内容。 這個不需要額外的處理,
但要注意在使用 FlyoutBase 的控制項時可以操作 LightDismissOverlayMode 屬性設定是否要顯示 smoke layer。
可參考 Modal vs light dismiss。
- Initial focus visual placement
- Focus engagement (非常重要)
Focus engagement 讓使用 gamepad 或 remote control 更容易操作 App。
設定 Focus engagement 不會影響 keyboard 或是其他輸入裝置。
設定 FrameElement 的 IsFocusEngagementEnabled = "True" 時,代表控制項請求 focus engagement。
用戶使用 gamepad 移動到該控制項時,需要按下 A/Select 按鈕才能與它互動。
操作完成之後需要按下 B/Back 按鈕才會離開該控制項,繼續瀏覽其他控制項。 - Focus trapping
Focus trapping 代表的是當用戶在瀏覽控制項時突然在某個控制項直接陷入到裏面,
造成用戶原本預期是到下一個控制項但是卻跑到裏面。
利用下圖的範例來説明: 有 3 個控制項: button1, slider, button2, 當用戶操作預期從 butotn1 到 button2 時會遇到卡在 slider 裏面,
不管左右移動都是在移動 slider 的光棒。 要解決這樣的問題有很多方式,最簡單從排版方式下手如下圖: 或者搭配 XY focus navigation and interaction 改寫控制項的 XY focus。
另外可以設定 Slider 的 IsFocusEngagementEnabled = "True",而操作的結果如下圖: - Items controls
其他設定 engagement 的控制項有: ListView, ListBox, GridView, FlipView。 如上圖要從 top button 移動到 bottom button,用戶會預期按往下按鈕就會直接到,
事實上當進去 ListView 時就會自動 focus 到第一個 item,而用戶要一路走到最後一個 item 才能離開 ListView 到 bottom button,
相反的如果要回去 top button 則是要走到第一個 item 才能出去。
這樣的操作會讓用戶抓狂,所以需要設定 IsFocusEngagementEnabled = "True",變成如下的操作流程: 如果是 ScrollViwer 需要考慮用法:- 内容有其他控制項,預設進去 ScrollViewr 會自動 focus 到第一個控制項,允許用戶左右移動瀏覽不同的控制項目;
- 内容為文字瀏覽或是圖片瀏覽時,則需要設定 IsFocusEngagementEnabled = "True",讓用戶方便進入與離開内容;
更可以設定 IsTapStop = "True",讓操作不需要透過 engage 的方式,而是焦點直接放在 ScrollViewer 直接 scroll 移動。
- Focus engagement defaults
有一些控制項因容易操作焦點迷失(例如自動 engage 造成 focus 消失)而預設的 IsFocusEngagementEnabled 是 false,
但我們還是可以打開它,下面列出幾個常使用的控制項:Control Focus engagement default CalendarDatePicker On FlipView Off GridView Off ListBox Off ListView Off ScrollViewer Off SemanticZoom Off Slider On
還有很多開發與設計上面需要注意的地方,
本篇先寫到這裏下一篇將繼續介紹: UI element sizing, TV-safe area, Color, Custom visual state trigger for Xbox, ... 等。
[補充]
- 由於 App 在 Xbox 上可用記憶體有限,建議跟 Desktop/Mobile 的專案切開,因爲記憶體的控制會是花最多時間的地方
- 上架到 Dev Center 時,可以搭配 TargetDeviceFamily 切開讓 Xbox 是另外一個安裝檔
- UWP App 在封裝時, Version 只能用到前 3 碼 (例如: 1.0.0.{不可用}),最後一碼是不可以用的,
因爲微軟把它用來顯示特定的設備,例如:Xbox 上安裝 App 之後會發現版本號碼變成了 1.0.0.6
更多詳細的内容,參考 What's new for developers in the latest update of UWP on Xbox One。
======
開發 Xbox 的 App 最大難度在於 focus 的控制,因爲 XAML 的組合會造成 focus 的困難或是迷失, 建議 Xbox 跟 Desktop/Mobile 分開 UI 設計比較好。
另外 Xbox 通常搭配電視(或是更大的屏幕)與眼睛距離較遠,内容簡單清楚是必要的。
最後因爲用戶沒有游標時,對於内容過長或是過多時都會讓用戶需要不斷地點擊方向鍵,是非常苦難的。
所以多做一些 Master Detail 的分層,讓畫面乾净與容易操作。 希望對大家有所幫助,謝謝。
References:
- What's new for developers in the latest update of UWP on Xbox One
- Designing for Xbox and TV
- UWP features that aren't yet supported on Xbox
- disable mouse mode
- Focus visual
- TV-safe area
- How to draw UI to the edge of the screen
- Read Colors to understand how to make your app look great to everybody!
- Building Great Universal Windows Platform (UWP) Apps for Xbox
- Adapt Your App for Xbox One and TV
- UWP Development 1: Building an Adaptive UI
- Web Apps Beyond the Browser: Cross-Platform Meets Cross Device
- System resources for UWP apps and games on Xbox One
- Introduction to multi-user applications
- How to use Fiddler with Xbox One when developing for UWP
- Developing Xbox One Applications
- UWP on Xbox One samples
- Keyboard interactions