iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 26
0

(本篇文章網誌版:http://shineright.blogspot.tw/2016/12/day-26-camera-aspect-ratio.html)

這個手機遊戲做了25天,都還不能實際以觸控的方式移動角色……今天終於要改變這一點啦!

到很久很久以前寫的PlayerMovement.cs,改一下程式碼:

public class PlayerMovement : MonoBehaviour
{
	//-舊程式碼-
    public float movementSpeed;
    public float minPosX;
    public float maxPosX;
	//-舊程式碼-
    
	//記錄螢幕中間的X軸
    private float midScreenPosX;
    
    void Start()
    {
        //初始螢幕中間X軸
        midScreenPosX = Screen.width / 2f;
    }
    
    void Update () 
    {
        float movement = 0f;
        
        //-舊程式碼- (鍵盤控制移動)
        movement = Input.GetAxis ("Horizontal") * movementSpeed * Time.deltaTime;
        //-舊程式碼-
        
		//觸控移動角色
        if (Input.touchCount > 0) {  //玩家正在觸控裝置
            Touch touch = Input.GetTouch (0); //取得玩家第一個觸控點
        
	        //檢查觸控點的位置在螢幕的左方還是右方,並計算出移動值
            movement = (touch.position.x < midScreenPosX ? -1f : 1f) * movementSpeed * Time.deltaTime;
        }
        
		//-舊程式碼-
        Vector3 newPos = new Vector3 (Mathf.Clamp(transform.position.x + movement, minPosX, maxPosX), transform.position.y, transform.position.z);
		transform.position = newPos;
		//-舊程式碼-
    }
}

首先,我宣告了一個儲存螢幕X軸中線的變數,因為我要讓玩家觸控左半邊螢幕時主角向左移動、觸控右半邊螢幕時主角向右移動。

Start()函數,我以Screen.width取得玩家裝置的螢幕寬度,除以2(也就是中間線),指定給midScreenPosX

觸控的重頭戲在Update()函數中。Input.touchCount會回傳目前玩家在裝置上的總觸控數,Input.touchCount > 0表示玩家至少有一根手指頭放在螢幕上。Input.GetTouch(int index)則用來取得玩家的觸控點,index值表示觸控點的索引值。例如,玩家把食指放在螢幕上不放開,接著又把中指放在螢幕上,Input.touchCount就會回傳2(兩個觸控點),Input.GetTouch(0)會回傳食指的觸控點,Input.GetTouch(1)會回傳中指的觸控點。

在此我只在乎玩家第一個在螢幕上的觸控點,也就是Input.GetTouch(0)Touch類別的position成員可取得觸控點的位置座標。我檢查touch.position.x < midScreenPosX (觸控點的X座標是否小於螢幕的中間線),如果成立,則把最終的移動數值乘一個-1f(向左移)。不成立則乘不影響數值的1f

回到Unity Editor,但是……該如何測試觸控呢?首先,準備好iPhone或Android手機,到App Store/Play Store下載Unity Remote 5,點開,會看到以下畫面:

http://ithelp.ithome.com.tw/upload/images/20161226/20103149EghVIukMML.png

跟著指示到上方選單選Edit→Project Settings→Editor,接著在Inspector欄中的Unity Remote標題下,把Device選為要測試的裝置。

進入Play Mode,Unity Editor就會把遊戲畫面自動投影在手機上了,Unity Remote 5在手機上的畫值會非常差,但這軟體主要是用來測試觸控的,所以不必太在意。

http://ithelp.ithome.com.tw/upload/images/20161226/20103149XFcyapFZid.png

觸控手機螢幕的左邊和右邊,主角就會跟著左右移動了。

然而,還有一個問題需要解決。如果手機的螢幕不符合9:16的長寬比,顯示出的畫面會被裁掉一些,或多出幾兩條藍色的邊邊。

http://ithelp.ithome.com.tw/upload/images/20161226/201031490o6vGs1bPT.png

要解決這點,必須在Main Camera上加上一段Script,讓它適應每個螢幕的長寬比。開一個名為「ScaleCameraInAspectRatio.cs」。

public class ScaleCameraInAspectRatio : MonoBehaviour 
{
	//長寬比,預設為9:16
    public float aspectRatio = 9f / 16f;
    
    void Start()
    {
        Camera cam = GetComponent<Camera> ();

		//裝置螢幕的長寬比
        float screenRatio = (float)Screen.width / (float)Screen.height;

		//裝置螢幕長寬比和目標長寬比的比值
        float scale = screenRatio / aspectRatio;
        
		//裝置螢幕長寬比大於目標長寬比(Main Camera高度應維持,寬度縮小)
        if (scale > 1f) {
            Rect pixRect = cam.pixelRect; //Main Camera的矩形

			//設定寬度
            pixRect.width = pixRect.height * aspectRatio;
            pixRect.y = 0f;

			//顯示寬度要在(過寬的)螢幕正中央,所以要除2
            pixRect.x = ((float)Screen.width - pixRect.width) / 2f;
            
			//設定新的Main Camera矩形
            cam.pixelRect = pixRect;
        }
        
		//裝置螢幕長寬比小於目標長寬比(Main Camera寬度應維持,長度縮小)
		else {
            Rect pixRect = cam.pixelRect;

			//設定高度
            pixRect.height = pixRect.width / aspectRatio;
            pixRect.x = 0f;

			//顯示高度要在(過高的)螢幕正中央,所以要除2
            pixRect.y = ((float)Screen.height - pixRect.height) / 2f;
            
			//設定新的Main Camera矩形
            cam.pixelRect = pixRect;
        }
    }
}

這段程式碼有點複雜,主要為了在過寬或過高的螢幕正常顯示,所以必須把Main Camera的長/高設定為和裝置螢幕一樣,再根據目標長寬比調整Main Camera的高/長。

把這段Script加在Main Camera上,並在場景中多加一個Camera,這是為了要讓遊戲在螢幕長寬比不是9:16的裝置上,在螢幕兩側以黑邊蓋住。

把新加Camera的Clear Flags設為Solid Color,Background設為黑色,Projection設為Orthographic,並把Depth設為-2(才能顯示在Main Camera後面)。最後,把Audio Listener Component取消掉,以免場景上同時擁有兩個Audio Listener。

進入Play Mode,現在不論裝置螢幕為何種比例,遊戲都能正常顯示了。

http://ithelp.ithome.com.tw/upload/images/20161226/20103149bCSw2AlxAF.png

待續。


上一篇
Day 25: 隨高度增加調整難度
下一篇
Day 27: 選擇角色、開始動畫
系列文
我要和天一樣高!!!(Unity 2D手機小遊戲開發日誌)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言