# Day 14 | 魔術方塊AR遊戲開發Part3 - 面的旋轉(上) ###### tags: `Unity` `AR手遊` 在上一篇我們完成了魔術方塊的偵測,今天我們要來製作面的旋轉。 > **目錄** > 選擇的面 > 面的旋轉 ## 選擇的面 建立SelectFace(): * 需要用到ReadCube及CubeState,更新面的資訊。 ``` private CubeState cubeState; private ReadCube readCube; private int layerMask = 1 << 8; void Start() { readCube = FindObjectOfType<ReadCube>(); cubeState = FindObjectOfType<CubeState>(); } ``` * 在手指點擊螢幕時,讀取目前狀態 * 判斷raycast是否偵測到面 * 建立List儲存面的資訊 * 如果偵測到面存在,選取該面 ``` if (Input.touchCount == 1) { readCube.ReadState(); RaycastHit hit; Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out hit, 100.0f, layerMask)) { GameObject face = hit.collider.gameObject; List<List<GameObject>> cubeSides = new List<List<GameObject>>() { cubeState.up, cubeState.down, cubeState.left, cubeState.right, cubeState.front, cubeState.back }; foreach (List<GameObject> cubeSide in cubeSides) { if (cubeSide.Contains(face)) { //選取該面 cubeState.PickUp(cubeSide); } } } } ``` 在CubeState()中新增PickUp()函式: ``` public void PickUp(List<GameObject> cubeSide) { foreach (GameObject face in cubeSide) { if (face != cubeSide[4]) { face.transform.parent.transform.parent = cubeSide[4].transform.parent; } } } ``` ## 面的旋轉 面的旋轉會以面的中心做為旋轉樞,因此在Scene中為每個旋轉樞新增PivotRotate() ![](https://i.imgur.com/jjZfocw.png) Rotate()函式: * 儲存觸控點的位置數值 * 並將需移動面存入List中 * 計算面向數值 ``` private List<GameObject> activeSide; private Vector3 localForward; private Vector3 touchRef; private bool dragging = false; public void Rotate(List<GameObject> side) { Touch touch = Input.GetTouch(1); activeSide = side; touchRef = touch.position; dragging = true; //計算面向數值 localForward = Vector3.zero - side[4].transform.parent.transform.localPosition; } ``` SpinRotate()函式: * 將旋轉數值初始化 * 並計算目前點擊點和上一次點擊點之間的差 ``` private Vector3 rotation; private float sensitivity = 0.4f; private void SpinSide(List<GameObject> side) { rotation = Vector3.zero; Touch touch = Input.GetTouch(1); Vector3 touchOffset = (touch.position - touchRef); } ``` 並加入判斷面,改變旋轉數值(rotation) ``` if (side == cubeState.up) { rotation.y = (touchOffset.x + touchOffset.y) * sensitivity * 1; } ``` 旋轉數值更新後,旋轉並紀錄點擊資訊 ``` transform.Rotate(rotation, Space.Self); touchRef = touch.position; ``` 在Update中加入下方程式,讓SpinSide()不會重複被呼叫 ``` void Update() { if (dragging) { SpinSide(activeSide); if (Input.GetMouseButtonUp(0)) { dragging = false; } } } ``` 若這時候執行畫面,會發現雖然可以旋轉面,但若在旋轉一半時,不再觸控螢幕,旋轉的面會停留在旋轉圖。 要解決這個問題,需要加上自動旋轉功能,這部分將在下ㄧ篇說明。 --- 以上就是面的旋轉(上),下一篇會是面的旋轉(下)+遊戲機制,明天見嘍!