[Win App] 處理Windows Snapped View的技巧

此文章隨時還會補充。

在一般的APP而言,snap view不外乎就是重新排列layout,但是遊戲就很麻煩了,很可能讀取的座標會有問題,因此遊戲的話比較不建議去處理在snap view下的遊玩情形。

目前我看到的處理方法約有三種:

第一種

進入snap view模式時,載入一張畫面,上面放個按鈕,要繼續玩就點一下,就會跳回全螢幕繼續,對於相當可能會是一個大工程的snap view來說,這種處理方法可能是比較有效率的,不然就是要一開始就要規劃好整個Layout的變化,不然重寫可是會累死人的。

點選

第二種

另一種處理方式是暫停app。主要是寫一個script以進行暫停,然後可以在其他地方呼叫它。

第三種

我有查到Unity有內建的東西似乎可以拿來用,叫做WSA.WindowSizeChanged,是在UnityEngine下。官方文件裡面有說,比方說可以用在snap時。
"This event occurs when window rendering size changes."
 我認為這是最接近於解決snap view的東西了,我的用法是,找所有View的super class,然後在他的initialize裡面加進去:

UnityEngine.WSA.Application.windowsSizeChanged += YourMethodName;

然後加入方法:

public void YourMethodName (int width, int height) {
//your code
}


第四種

輸出成vs檔案後在App.cs中處理。這邊主要是依賴windows的framwork了:
  1. 註冊螢幕大小變化的事件:WindowSizeChangedEvent
  2. 使用匿名方法呼叫,就是和1.一起。
  3. 判斷是否為全螢幕的狀態:ApplicationView.GetCurrentView.IsFullScreen。
以我來說,我是在App.cs內的SetWindow方法內註冊事件的:




基本上運作是正常的,只是在縮小時暫停,畫面會變黑。還不太確定原因為何。

補充

順便補一點解釋。以下都是使用C#的語言。適用於Win 8。不適用於Win 8.1。

你要如何取得你的view目前的狀態呢?可以透過WinRT裡面的ApplicationViewState enumeration來取得:

var CurrentViewState = Windows.UI.ViewManagement.ApplicationView.Value;

這邊的Value可以取得正在運行的app的view的狀態,可以知道是不是Snapped。

Resize event和View state change event的次序是已經決定的,所以view state event(以及相關的callback函數)會在resize event之前啟動。

若由view state change觸發的callback函數中搜尋display area size,可能會是錯的,舉例來說,從snap的寬度為320px轉變成橫向全螢幕時,view state會是fullscreen-landscape,但是寬度尺寸是320px。

但這個做法的最大問題是,Unity內部好像不能使用Windows的namespace,如果你要用,那要自己建立dll插入,這倒不是一件容易的事情。而且Win8.1之後就沒有snapped了。

Win8.1已經沒有snap view,而是要設定最小寬度,所以如果可以偵測目前App的寬度,那我認為是比較好的處理方法。

對於直接處理視窗大小的作法是:

取得目前App啟動之視窗的大小:Windows.UI.Xaml.Window.Current.Bound
(回傳Rect。Windows.UI.Xaml是namespace,Window是class,Current是屬性,取得應用程式目前已啟動的視窗,Bound是取得應用程式視窗的高度及寬度,作為Rect值)。



補充二

這一部分很重要,unity提供了一樣東西:Screen.fullscreen,這可以判斷是否為全螢幕,但是,在unity以及Windows模擬器下運行時,他是false的!我試了,如果在本機電腦運行的話,才能夠判斷為全螢幕。

留言