요약
알고리즘 작성 전에 고려 사항으로 색상 블록을 합쳐 하나의 큐브를 완성한 것과 공전 시 이동 경로가 서로 다른 것을 확인하고 작성해야 한다. 코드를 보면 temp가 특이한 역할을 하고 있는 것이 보이는데, 이는 이전 루빅스 큐브 층 확인 알고리즘에서 마우스를 클릭하는 동안 회전하는 값을 활용하여 정렬 시 보정을 주는 역할을 한다.
알고리즘
알고리즘 작성 전에 몇 가지 고려해야 할 사항이 있다. 먼저 큐브 위치 확인 알고리즘으로 들어온 정보는 정확하게 해당 큐브가 아닌 큐브 색상을 가져오는 것이다.
위 그림을 보면 색상 블록을 합쳐 하나의 큐브를 완성한 것을 알 수 있다. 그렇기 때문에 정확한 층을 파악할 수 있는 것이지만, 큐브 위치를 이동시킬 때에는 해당 블록의 부모인 검은색 큐브를 움직여야 한다.
검은색 큐브를 움직일 때 또한 고려해야 할 사항이 있다. 내부의 4개의 큐브는 그림과 같이 빨간 선을 따라 움직이지만, 외부의 4개의 큐브는 파란 선을 따라 움직인다.
CubeMovement.cs
public class CubeMovement : MonoBehaviour
{
private List<GameObject> nowCube;
private CubeState cubeState;
public int floor;
float angle = 0;
bool auto = false;
void Start()
{
cubeState = FindObjectOfType<CubeState>();
}
void Update()
{
// 마우스 우측 클릭이 올라가면 자동으로 90도 각도로 맞춰 지도록 함
if (Input.GetMouseButtonUp(0))
{
auto = true;
StartRotate(nowCube, 0);
angle = 0;
auto = false;
}
}
필요한 클래스나 변수를 초기화해야 한다. 특이한 점은 auto인데, auto는 큐브가 돌아가도 정렬된 상태를 유지하기 위해 사용한다.
// 마우스 좌클릭이 되는 순간과 현재 감지되고 있는 값을 뺀 값을 받는중
public void StartRotate(List<GameObject> side, float inAngle)
{
float temp = 0;
nowCube = side;
if (!auto)
{
angle += inAngle;
}
else
{
temp = -angle + RotateToRightAngle(angle);
angle = RotateToRightAngle(angle);
}
if (side == cubeState.front || side == cubeState.back)
{
for (int i = 0; i < 8; i++)
{
if (i % 2 == 0)
{
side[i].transform.parent.localPosition = new Vector3(floor, Sin(angle, i), Cos(angle, i));
}
else
{
side[i].transform.parent.localPosition = new Vector3(floor, SinSqrt(angle, i), CosSqrt(angle, i));
}
}
for (int i = 0; i < 9; i++)
{
Debug.DrawRay(-side[8].transform.parent.transform.parent.position, -side[i].transform.parent.transform.parent.right*1000, Color.red, 0.1f);
side[i].transform.parent.rotation = Quaternion.AngleAxis(inAngle + temp, -side[i].transform.parent.transform.parent.right) * side[i].transform.parent.rotation;
}
}
if (side == cubeState.right|| side == cubeState.left)
{
for (int i = 0; i < 8; i++)
{
if (i % 2 == 0)
{
side[i].transform.parent.localPosition = new Vector3(Sin(angle, i), Cos(angle, i), floor);
}
else
{
side[i].transform.parent.localPosition = new Vector3(SinSqrt(angle, i), CosSqrt(angle, i), floor);
}
}
for (int i = 0; i < 9; i++)
{
Debug.DrawRay(-side[i].transform.parent.transform.parent.position, side[i].transform.parent.transform.parent.forward*1000, Color.red, 0.1f);
side[i].transform.parent.rotation = Quaternion.AngleAxis(inAngle + temp, -side[i].transform.parent.transform.parent.forward) * side[i].transform.parent.rotation;
}
}
if (side == cubeState.up || side == cubeState.down)
{
for (int i = 0; i < 8; i++)
{
if (i % 2 == 0)
{
side[i].transform.parent.localPosition = new Vector3(Cos(angle, i), floor, Sin(angle, i));
}
else
{
side[i].transform.parent.localPosition = new Vector3(CosSqrt(angle, i), floor, SinSqrt(angle, i));
}
}
for (int i = 0; i < 9; i++)
{
Debug.DrawRay(-side[i].transform.parent.transform.parent.position, -side[i].transform.parent.transform.parent.up*1000, Color.red);
side[i].transform.parent.rotation = Quaternion.AngleAxis(inAngle + temp, -side[i].transform.parent.transform.parent.up) * side[i].transform.parent.rotation;
}
}
}
앞서 설명한 것처럼 transform.parent를 통해 검은색 큐브의 위치를 적절한 위치의 삼각함수를 활용하여 공전시킨 후, 각 큐브를 자전시킨다.
이때 temp가 특이한 역할을 하고 있는 것이 보이는데, 이는 이전 루빅스 큐브 층 확인 알고리즘에서 보내온 정보 중 하나인 마우스를 클릭하는 동안 회전하는 값을 측정하여 층을 정렬시킨다. 식은 단순하게 돌려야 할 각도에서 돌아간 각도를 빼서 남은 부분을 돌리도록 하였다.
public float SinSqrt(float inAngle, int count)
{
return Mathf.Sin(Mathf.Deg2Rad * (inAngle + 45 * count)) * Mathf.Sqrt(2);
}
public float CosSqrt(float inAngle, int count)
{
return Mathf.Cos(Mathf.Deg2Rad * (inAngle + 45 * count)) * Mathf.Sqrt(2);
}
public float Sin(float inAngle, int count)
{
return Mathf.Sin(Mathf.Deg2Rad * (inAngle + 45 * count));
}
public float Cos(float inAngle, int count)
{
return Mathf.Cos(Mathf.Deg2Rad * (inAngle + 45 * count));
}
public float RotateToRightAngle(float inAngle)
{
return Mathf.Round(inAngle / 90) * 90;
}
}
해당 함수들은 삼각함수를 계산하기 위해 작성한 함수들이다.
'Unity > 루빅스 큐브 개발 일지' 카테고리의 다른 글
[Unity] 루빅스 큐브 층 확인 알고리즘 (0) | 2025.01.20 |
---|---|
[Unity] 큐브 위치 확인 알고리즘 (0) | 2025.01.19 |
[Unity] 루빅스 큐브 층 회전 이론 (0) | 2025.01.19 |
[Unity] 루빅스 큐브 회전 (0) | 2025.01.19 |
[Unity] 루빅스 큐브 오브젝트 만들기 (0) | 2025.01.19 |