Day 13 | 魔术方块AR游戏开发Part2 - 魔术方块侦测

在上一篇文章中,我们完成魔术方块的建立及旋转,今天我们要来完成魔术方块的侦测。

目录
魔术方块的侦测
读取面状态

魔术方块的侦测

魔术方块状态

建立CubeState()用来储存魔术方块目前状态,新增List分别储存各面物件

 public List<GameObject> front = new List<GameObject>();

射线设置

首先要在Scene中新增好射线起始位置,新增Empty GameObject,并将外观设定成点。

并且为魔术方块的每个面都新增一个射线,并将其位置放在各面的正上方。

将这些射线放在群组下(Rays)。

建立射线程序:

  • 为各射线都宣告一个变数储存射线位置 public Transform tUp;
  • 魔术方块的面为3x3,因此射线也宣告成3x3的形式,宣告rayCount做为控制回圈变数
  • 并利用回圈生成射线,生成射线顺序从左上到右下:
    |0|1|2|
    |3|4|5|
    |6|7|8|
  • 为射线命名完後,设定旋转数值,并回传射线
public GameObject empty; //射线起始的位置
    List<GameObject> BuildRays(Transform rayTransform, Vector3 direction)
    {
        int rayCount = 0;
        List<GameObject> rays = new List<GameObject>();

        for (int y = 1; y > -2; y--)
        {
            for (int x = -1; x < 2; x++)
            {
                Vector3 startPos = new Vector3( rayTransform.localPosition.x + x,
                                                rayTransform.localPosition.y + y,
                                                rayTransform.localPosition.z);
                GameObject rayStart = Instantiate(empty, startPos, Quaternion.identity, rayTransform);
                rayStart.name = rayCount.ToString(); //射线编号
                rays.Add(rayStart);//新增射线
                rayCount++;
            }
        }
        rayTransform.localRotation = Quaternion.Euler(direction);
        return rays;
    }

为魔术方块的不同面,分别建立3x3的射线

 void SetRayTransforms()
    {
        upRays = BuildRays(tUp, new Vector3(90, 90, 0));
        downRays = BuildRays(tDown, new Vector3(270, 90, 0));
        leftRays = BuildRays(tLeft, new Vector3(0, 180, 0));
        rightRays = BuildRays(tRight, new Vector3(0, 0, 0));
        frontRays = BuildRays(tFront, new Vector3(0, 90, 0));
        backRays = BuildRays(tBack, new Vector3(0, 270, 0));
    }

读取面状态

Raycast运用

为了防止射线侦测到其他物体,需要新增一个图层,并将各魔术方块的面图层都改成该图层。

并在程序码中新增图层遮罩。

 private int layerMask = 1 << 8;

读取面程序运用到Unity中的Physics.Raycast

  • 新增faceHit储存射线碰撞的所有面
  • 建立Raycast,并判断是否与魔术方块面相交
  • 使用DrayRay,将射线画出来,方便後续除错
 public List<GameObject> ReadFace(List<GameObject> rayStarts, Transform rayTransform)
    {
        List<GameObject> facesHit = new List<GameObject>();

        foreach (GameObject rayStart in rayStarts)
        {
            Vector3 ray = rayStart.transform.position;
            RaycastHit hit;

            if (Physics.Raycast(ray, rayTransform.forward, out hit, Mathf.Infinity, layerMask))
            {
                Debug.DrawRay(ray, rayTransform.forward * hit.distance, Color.yellow);
                facesHit.Add(hit.collider.gameObject);
            }
            else
            {
                Debug.DrawRay(ray, rayTransform.forward * 1000, Color.green);
            }
        }
        return facesHit;
    }

读取面的状况

使用ReadState读取各面目前状况

    public void ReadState()
    {
        cubeState = FindObjectOfType<CubeState>();

        cubeState.up = ReadFace(upRays, tUp);
        cubeState.down = ReadFace(downRays, tDown);
        cubeState.left = ReadFace(leftRays, tLeft);
        cubeState.right = ReadFace(rightRays, tRight);
        cubeState.front = ReadFace(frontRays, tFront);
        cubeState.back = ReadFace(backRays, tBack);
    }

以上就是魔术方块的侦测,下一篇会是魔术方块面的旋转,明天见!


<<:  Day12: 【TypeScript 学起来】只有 TS 才有的型别: Literal Types(字面值型别) / Tuple (元组)

>>:  Pascal 语言和你 SAY HELLO!!

[Day 2]我也好想要有监定技能(前端篇)

如果被老板发现我们可以一眼监定出需求的细节和问题的原因,那我们的工作量会不会变更多 Mock的第一步...

1.unity安装、学习资源、游戏规划

安装 官方网站:Download - Unity 注册、安装 注册UnityID 安装Unity H...

Day 21 中场休息,来做点酷东西(重构 class)

今天做了 重构程序码,写了一个基本的 component class 让 ProjectInput ...

[Day6] 初见输入系统

今日目标 键盘滑鼠输入 GLFW Input Callback 第一篇的时候,有简单的介绍glfw管...

Day2-JavaScript(JS)与TypeScript(TS)的差异比较

第二天,我们来谈谈JavaScript(JS)与TypeScript(TS)的比较吧! 使用Java...