Unity/루빅스 큐브 개발 일지
[Unity] 루빅스 큐브 회전
suppresswisely
2025. 1. 19. 17:51
요약
루빅스 큐브가 어떻게 맞춰졌는지 보기 위해서는 큐브 전체를 회전하여 확인하여야 한다. 이를 위해 Target이라는 기준점을 활용하여 큐브를 전체 회전시키고 정렬하는 알고리즘을 작성하였다.
루빅스 큐브 회전
시작전에 알아야 할 사실은 루빅스 큐브에는 Target이 존재하는데 이는 루빅스 큐브를 회전한 수 정렬에 필요한 요소이다.
RotateBigCube.cs
public class RotateBigCube : MonoBehaviour
{
Vector2 firstPressPos;
Vector2 secondPressPos;
Vector2 currentSwipe;
Vector3 previousMousePosition;
Vector3 mouseDelta;
public GameObject target;
float speed = 200f;
void Update()
{
Swipe();
Drag();
}
firstPressPos: 처음 마우스를 클릭한 지점
secondPressPos: 다음 마우스를 클릭한 지점
currentSwipe: 마우스의 클릭하고 놓은 지점의 방향값
previousMousePosition: 루빅스 큐브를 회전시키기 위해 이전값을 저장함
mouseDelta: 저장된 마우스 이전값과 현재값을 통해 변화량을 구함
target: 루빅스 큐브를 90도 각도로 정렬시키기 위한 기준
// Swipe(); Drag();는 우클릭을 통해 작동하는 함수
// 마우스를 클릭하는 중을 인식하여 큐브를 돌리는 방향을 인식
// 미리 회전할 부분을 보여주는 역할
void Drag()
{
// 마우스 클릭하기 전의 값을 통해 내가 움직이는 거리를 확인하여 방향을 회전
if (Input.GetMouseButton(1))
{
mouseDelta = Input.mousePosition - previousMousePosition;
mouseDelta *= 0.1f;
transform.rotation = Quaternion.Euler(mouseDelta.y, -mouseDelta.x, 0) * transform.rotation;
}
else
{
// Swipe함수에서 돌아간 target 루빅스 큐브와 실제 루빅스 큐브각도가 맞지 않을 경우
//큐브를 Time.deltaTime을 통해 돌아가는 애니메이션을 보여줌
if (transform.rotation != target.transform.rotation)
{
var step = speed * Time.deltaTime;
transform.rotation = Quaternion.RotateTowards(transform.rotation, target.transform.rotation, step);
}
}
// 마우스 클릭하기 전의 값을 저장
previousMousePosition = Input.mousePosition;
}
Drag()는 루빅스 큐브를 회전시키기 위해 변화량을 구해 즉각적으로 회전시킨다. 다만 루빅스 큐브의 기준점과 같지 않다면 각도를 맞추기 위해 돌아간다.
// 마우스 클릭한 순간, 마우스를 때는 순간을 기억하여 한번에 루빅스 큐브를 돌림
void Swipe()
{
//마우스 클릭순간을 인식후 기억
if (Input.GetMouseButtonDown(1))
{
firstPressPos = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
}
//마우스 클릭후 클릭한 순간의 값을 활용하여 큐브를 회전
if (Input.GetMouseButtonUp(1))
{
secondPressPos = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
currentSwipe = new Vector2(secondPressPos.x - firstPressPos.x, secondPressPos.y - firstPressPos.y);
currentSwipe.Normalize();
if (LeftSwipe(currentSwipe))
{
target.transform.Rotate(0, 90, 0, Space.World);
}
else if (RightSwipe(currentSwipe))
{
target.transform.Rotate(0, -90, 0, Space.World);
}
else if (UpLeftSwipe(currentSwipe))
{
target.transform.Rotate(90, 0, 0, Space.World);
}
else if (UpRightSwipe(currentSwipe))
{
target.transform.Rotate(0, 0, -90, Space.World);
}
else if (DownLeftSwipe(currentSwipe))
{
target.transform.Rotate(0, 0, 90, Space.World);
}
else if (DownRightSwipe(currentSwipe))
{
target.transform.Rotate(-90, 0, 0, Space.World);
}
}
}
Swipe()는 루빅스 큐브의 기준점을 회전시키는 알고리즘으로 마우스가 클릭을 통해 얼마나 돌아간 방향값을 구하고 단위 벡터로 만들어 이를 활용하여 어느 쪽으로 돌렸는지 확인하는 알고리즘이다.
// 벡터의 정규화를 통한 값을 받아 어느 방향으로 회전시킬지 정하는 함수
bool LeftSwipe(Vector2 swipe)
{
return currentSwipe.x < 0 && currentSwipe.y > -0.5f && currentSwipe.y < 0.5f;
}
bool RightSwipe(Vector2 swipe)
{
return currentSwipe.x > 0 && currentSwipe.y > -0.5f && currentSwipe.y < 0.5f;
}
bool UpLeftSwipe(Vector2 swipt)
{
return currentSwipe.y > 0 && currentSwipe.x < 0f;
}
bool UpRightSwipe(Vector2 swipt)
{
return currentSwipe.y > 0 && currentSwipe.x > 0f;
}
bool DownLeftSwipe(Vector2 swipt)
{
return currentSwipe.y < 0 && currentSwipe.x < 0f;
}
bool DownRightSwipe(Vector2 swipt)
{
return currentSwipe.y < 0 && currentSwipe.x > 0f;
}
}
해당 함수들은 단위 벡터를 이용하여 어느 방향으로 돌아갔는지 확인하는 함수들이다.