본문 바로가기

Unity/루빅스 큐브 개발 일지

[Unity] 루빅스 큐브 층 확인 알고리즘

요약

클릭한 큐브가 어느 층인지 확인하기 위해 foreach 문으로 큐브 층마다 Contains()로 확인한다. 이후 해당 정보를 통해 루빅스 큐브 층 회전 알고리즘으로 전달된다.


알고리즘

루빅스 큐브 층을 회전 시키기 위해서 좌클릭한 곳이 어떤 층인지 확인할 필요가 있다.

SelectFace.cs

public class SelectFace : MonoBehaviour
{
    private List<GameObject> activeSide;
    private Vector3 mouseRef;
    CubeMovement cubeMovement;
    CubeState cubeState;
    ReadCube readCube;
    Vector3 rotation;

    int layerMask = 1 << 8;

    void Start()
    {
        readCube = FindObjectOfType<ReadCube>();
        cubeState = FindObjectOfType<CubeState>();
        cubeMovement = FindObjectOfType<CubeMovement>();
        readCube.ReadState();
    }

기본적인 클래스들을 초기화해 주고 큐브의 위치를 확인한다.

 

    void Update()
    {
        // 마우스 좌클릭이 되는 순간
        if (Input.GetMouseButtonDown(0))
        {
            mouseRef = Input.mousePosition;
            // SpinSide함수에 사용될 처음 들어온 마우스 값
            readCube.ReadState();
            RaycastHit hit;
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            // 클릭한 분에 Ray가 작동하여 충돌된 오브젝트를 확인
            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
                };

                // cubeState에 있는 리스트들을 확인하여 충돌된 오브젝트가 어느 방향에 있는지 확인
                // (Contains는 요소를 파악하는데 게임 오브젝트는 같은 이름이여도 다른 오브젝트이면 다른것으로 인식함)
                foreach (List<GameObject> cubeSide in cubeSides)
                {
                    if (cubeSide.Contains(face))
                    {
                        activeSide = cubeSide;
                    }
                }
            }
        }
        if (Input.GetMouseButton(0))
        {
            SpinSide(activeSide);
        }
    }

좌클릭 시 클릭한 오브젝트를 확인하고 현재 위치에 있는 큐브들 중 어떤 큐브인지 foreach 문으로 확인한다. 이때 Contains()로 해당 오브젝트가 포함되어 있으면 True를 반환한다. 이를 통해 클릭한 층이 어느 곳인지 확인할 수 있다.

 

    // 마우스 위지를 감지하고 회전을 주는 함수
    private void SpinSide(List<GameObject> side)
    {
        
        rotation = Vector3.zero;
        // 마우스 좌클릭이 되는 순간과 현재 감지되고 있는 값을 뺀 값을 가져옴
        Vector3 mouseOffest = Input.mousePosition - mouseRef;

        if (side == cubeState.up)
        {
            cubeMovement.floor = 1;
            rotation.y = (mouseOffest.x + mouseOffest.y) * 0.4f * -1;
            cubeMovement.StartRotate(side, rotation.y);
        }
        if (side == cubeState.down)
        {
            cubeMovement.floor = -1;
            rotation.y = (mouseOffest.x + mouseOffest.y) * 0.4f * -1;
            cubeMovement.StartRotate(side, rotation.y);
        }
        if (side == cubeState.left)
        {
            cubeMovement.floor = 1;
            rotation.z = (mouseOffest.x + mouseOffest.y) * 0.4f * -1;
            cubeMovement.StartRotate(side, rotation.z);
        }
        if (side == cubeState.right){
            cubeMovement.floor = -1;
            rotation.z = (mouseOffest.x + mouseOffest.y) * 0.4f * -1;
            cubeMovement.StartRotate(side, rotation.z);
        }
        if (side == cubeState.front)
        {
            cubeMovement.floor = -1;
            rotation.x = (mouseOffest.x + mouseOffest.y) * 0.4f * -1;
            cubeMovement.StartRotate(side, rotation.x);
        }
        if (side == cubeState.back)
        {
            cubeMovement.floor = 1;
            rotation.x = (mouseOffest.x + mouseOffest.y) * 0.4f * -1;
            cubeMovement.StartRotate(side, rotation.x);
        }
        mouseRef = Input.mousePosition;
    }
}

해당 함수는 cubeMovement.StartRotate()로 회전을 주기 전에 클릭한 곳의 층이 어느 곳인지 확인하며, 실제로 아래층인지 위층인지 구분하기 위한 floor, 마우스 클릭하며 돌린 회전 값 rotation, 돌리고 있는 층 side를 루빅스 큐브 층 회전 알고리즘에 전달한다.