스니펫VR예제같은 그림 맞추는 퍼즐

같은 그림 맞추는 퍼즐

VR 콘텐츠에서 많이 사용되는 같은 그림 맞추기 퍼즐을 만들어봅시다.


match-same-imges

위에는 완성 결과입니다.
박스를 눌렸을 때, Y축으로 돌아가며 같은 그림이 맞춰졌을 때, 모든 박스가 사라지는 것을 확인할 수 있습니다.

박스 오브젝트 추가하기

레드브릭 스튜디오 내 에셋을 활용해서 박스를 3개 만들어 줍니다.


match-same-img_1

아래와 같은 스크립트를 작성해줍니다.

이때, 위에서 제작한 박스 오브젝트의 이름을 아래 스크립트를 참고해서 바꿔주셔야 합니다.
(randomBox1, randomBox2 …)

// VR Option Setting
const avatar = REDBRICK.AvatarManager.createDefaultAvatar();
const camera = WORLD.getObject("MainCamera");
const followingCamera = avatar.setFollowingCamera(camera);
avatar.setDefaultController();
followingCamera.useVR({VRObject: avatar});
 
const randomBoxes = []; // 박스 오브젝트 배열
const fristState = {0 : 0 , 1: 90, 2: 180}; // 처음 박스 돌아가있는 상태 저장
const isTurning = {0 : false , 1: false, 2: false}; // 현재 돌아가고 있는 중인지
 
function Start() {
    // 박스 오브젝트 가져와서 배열에 저장
    for(let i=1; i<=3; i++){
        let object = WORLD.getObject("randomBox" + i);
        randomBoxes.push(object);
    }
 
    randomBoxes.forEach((box, index) => {
        // 박스를 클릭할 경우
        box.onClick(() => {
            // 박스 돌리기
            turnBox(index);
        });
    });
 
}
 
// 박스 돌리고 그림 일치하는지 확인
function turnBox(index){
    if(isTurning[index]) return;
    isTurning[index] = true;
 
    randomBoxes[index].turn(0,90,0,2); // 2초 동안 박스 회전시키기
    fristState[index] += 90; // 회전 값 더해주기
    if(fristState[index] == 360) fristState[index] = 0;
    // 2.5 초 후, 그림 일치하는지 확인
    setTimeout(() => {
        isTurning[index] = false;
        checkSameRotateAllBox();
    }, 2500);
}
 
// 박스 그림 일치하는지 확인
function checkSameRotateAllBox(){
    let isSame = true;
 
    let currentRotate = fristState[0];
    // 현재 회전 값이 셋 다 일치하는지 확인
    for(let i=1; i< 3; i++){
        if(currentRotate !== fristState[i]){
            isSame = false;
        }
    }
 
    // 그림이 다 일치 한다면
    if(isSame){
        // 박스 다 사라지게 설정
        randomBoxes.forEach((box) => {
            box.kill();
        });
    }
}

스크립트에 맞춰서 오브젝트 세팅 및 회전 값 설정

레드브릭 에셋을 쓸 경우, 실제 오브젝트가 상위 객체(1번)이 아닌 하위 객체(2번)에 들어가는 것을 확인할 수 있습니다.
이때, OnClick 함수를 직접적인 오브젝트가 아닌 상위 객체(1번)에 달 경우, 클릭한 것에 대해 제대로 인식하지 못하는 오류가 있습니다. 그렇기 때문에, 꼭 하위 객체(2번)를 스크립트 상에 가져와 OnClick 을 달아주도록 해야합니다.
또한, 코드 상에 처음 회전 각도가 const fristState = {0 : 0 , 1: 90, 2: 180} 라고 설정하였기 때문에 이에 맞게 3번처럼 각도를 세팅해줍니다.


match-same-img_2

⚠️

추가적으로 if(box.rotation.y.toFixed(2) !== num) 이와 같이 직접 박스 회전 값을 가져와서 비교할 경우, 값이 45.45 / 44.78 이런 식으로 나와서 제대로 확인이 안될 수 있습니다.
그렇기 때문에 위에처럼 따로 배열을 설정해주는 게 좋습니다.

테스트 실행하기

이후 테스트 해보면, 처음 화면과 같이 작동하는 것을 확인하실 수 있습니다.
현재 코드에서는 randomBoxes[index].turn(0,90,0,2) 으로 설정되어 있어 Y축이 회전하지만 이를 수정해서 다른 축 회전 퍼즐도 만들 수 있습니다.