iT邦幫忙

2021 iThome 鐵人賽

DAY 14
0
Mobile Development

從無到有! Unity AR手遊開發日誌-以山海異聞錄為例系列 第 14

Day 14 | 魔術方塊AR遊戲開發Part3 - 面的旋轉(上)

在上一篇我們完成了魔術方塊的偵測,今天我們要來製作面的旋轉。

目錄
選擇的面
面的旋轉

選擇的面

建立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()

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;
            }
        }       
    }

若這時候執行畫面,會發現雖然可以旋轉面,但若在旋轉一半時,不再觸控螢幕,旋轉的面會停留在旋轉圖。

要解決這個問題,需要加上自動旋轉功能,這部分將在下ㄧ篇說明。


以上就是面的旋轉(上),下一篇會是面的旋轉(下)+遊戲機制,明天見嘍!


上一篇
Day 13 | 魔術方塊AR遊戲開發Part2 - 魔術方塊偵測
下一篇
Day 15 | 魔術方塊AR遊戲開發Part4 - 面的旋轉(下)+遊戲機制
系列文
從無到有! Unity AR手遊開發日誌-以山海異聞錄為例30

尚未有邦友留言

立即登入留言