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

若这时候执行画面,会发现虽然可以旋转面,但若在旋转一半时,不再触控萤幕,旋转的面会停留在旋转图。

要解决这个问题,需要加上自动旋转功能,这部分将在下ㄧ篇说明。


以上就是面的旋转(上),下一篇会是面的旋转(下)+游戏机制,明天见喽!


<<:  常见网路问题(四):为什麽还是上不了网?DNS Server 设定错误,DNS 的简介及小工具 ping

>>:  [Day 13] 阿嬷都看得懂的基础 CSS 选择器

DAY15: HTTP GET请求

今天要介绍的有点偏向处理HTPP请求的後续,在Web开发中,HTTP请求中最常用的就是Get与Pos...

Day 27 - Detect Capital

大家好,我是毛毛。ヾ(´∀ ˋ)ノ 废话不多说开始今天的解题Day~ 520. Detect Cap...

Day29 - Float

Float float:用来将区块并排时可以使用,当设定浮动时,其父层会抓不到子层的高度 left:...

【Day23】 Transformer 新手包 (三)

Positional Encoding 怎麽做的 书接昨日,我们说 Positional Encod...

#24 数据中中的特徵相关性(3)

基於上篇,有了数据特徵,再来就可以把欧氏距离发展为马氏距离公式 马氏距离公式(Mahalanobis...