티스토리 뷰

728x90

직소퍼즐 구현하기 제 2편입니다. 

지난 포스팅에서 조각을 마우스 드래그를 통해 움직이고 기준위치에 놓을 때 딱 들어맞도록 스냅하는 기능을 구현해보았습니다.

 

이번에는 N개의 퍼즐조각을 모두 올바른 위치에 놓았을때 퍼즐이 클리어 되도록 구현하는 방법을 알아보겠습니다.

 

1.퍼즐 전체 오브젝트 계층구조 구현

먼저 에디터에서 퍼즐에 필요한 오브젝트들을 씬에 배치하여 계층 구조를 설정하겠습니다.

오브젝트들을 다음과 같이 배치합니다.

PuzzlePieceN은 N번째 퍼즐조각입니다. PuzzlePosN은 N번째 퍼즐조각이 와야할 기준위치입니다.

 

그리고 전체 퍼즐을 관리할 스크립트 하나를 생성하고 퍼즐의 루트 오브젝트(JigsawPuzzle)에 컴포넌트로 추가합니다.

 

생성한 스크립트에서 퍼즐조각과 퍼즐위치를 참조하기 위해 GameObject변수 2개를 선언하고 에디터에서 할당합니다.

 

 

2. 퍼즐조각 OnEndDrag메서드 수정

1편에서 작성한 OnEndDrag를 온전한 퍼즐 기능 구현을 위해 다음과 같이 수정합니다.

 

public class PuzzlePiece : MonoBehaviour, IDragHandler, IEndDragHandler
{
    public int snapOffset = 30;
    public JigsawPuzzle puzzle;
    public int piece_no;
    bool CheckSnapPuzzle()
    {
        for (int i = 0; i < puzzle.puzzlePosSet.transform.childCount; i++)
        {
            //위치에 자식오브젝트가 있으면 이미 퍼즐조각이 놓여진 것입니다.
            if(puzzle.puzzlePosSet.transform.GetChild(i).childCount != 0)
            {
                continue;
            }
            else if (Vector2.Distance(puzzle.puzzlePosSet.transform.GetChild(i).position, transform.position) < snapOffset)
            {
                transform.SetParent(puzzle.puzzlePosSet.transform.GetChild(i).transform);
                transform.localPosition = Vector3.zero;
                return true;
            }
        }
        return false;
    }
 	//...
    public void OnEndDrag(PointerEventData eventData)
    {
        //일치하는 위치가 없을 경우 부모자식 관계를 해제합니다.
        if (!CheckSnapPuzzle())
        {
            transform.SetParent(puzzle.puzzlePieceSet.transform);
        }

        if (puzzle.IsClear())
        {
            Debug.Log("Clear");
        }
    }

    // Start is called before the first frame update
    void Start()
    {
        piece_no = gameObject.name[gameObject.name.Length - 1] - '0';
    }
}

퍼즐조각을 놓았을 때 위치 offset보다 작으면 해당 위치의 자식오브젝트로 변경합니다.

이미 자식오브젝트가 있다면 해당 위치에는 퍼즐조각이 놓여진것이므로 자식오브젝트로 변경하지 않습니다.

모든 위치와 offset보다 멀 경우 퍼즐조각의 부모를 기존 퍼즐조각 집합 오브젝트(PuzzlePieceSet)로 변경합니다.

 

몇번째 퍼즐조각인지 판별하기 위해 int변수를 선언하고 Start생명주기 메서드에서 번호를 초기화합니다.

 

그리고 퍼즐조각을 놓을때마다 퍼즐이 완성되었는지 판별합니다.

 

3.퍼즐 완성 여부 판별하기

이제 퍼즐 스크립트에서 퍼즐이 완성되었는지를 판별할 IsClear메서드를 작성합니다.

    public bool IsClear()
    {
        for(int i = 0; i < puzzlePosSet.transform.childCount; i++)
        {
            //퍼즐위치의 자식이 없으면 모든 퍼즐조각이 놓여지지 않은것입니다.
            if(puzzlePosSet.transform.GetChild(i).childCount == 0)
            {
                return false;
            }
            //퍼즐조각의 번호와 퍼즐 위치 번호가 일치하지 않으면 퍼즐은 완성되지 않은것입니다.
            if(puzzlePosSet.transform.GetChild(i).GetChild(0).GetComponent<PuzzlePiece>().piece_no != i)
            {
                return false;
            }
        }
        return true;
    }

자식오브젝트가 없는 위치가 있을 경우 모든 퍼즐조각이 놓이지 않은 것입니다.

모든 위치에 조각이 놓여졌다 하더라도 0번쨰 위치에 0번째 조각이 온것이 아니라면 퍼즐은 틀린것입니다.

 

4.퍼즐 동작 확인하기

이제 실행하여 퍼즐조각을 올바르게 놓은후 퍼즐이 완성되었을 때 Clear가 출력되는지 확인합니다.

 

퍼즐 초기

 

 

퍼즐 완성 후

이렇게 순서에 맞게 퍼즐을 놓았을 때만 Clear가 출력되면 성공입니다.

만약 순서가 1 2 4 3 처럼 잘못되었을 때 Clear가 출력되면 잘못된 부분을 수정해야합니다.

 

1편 링크 : game-happy-world.tistory.com/43

 

유니티 - 직소퍼즐구현1(마우스로 UI제어 이동)

유니티에서 조각난 그림조각들을 올바른 위치에 배치하여 그림을 완성시키는 직소퍼즐 구현방법에 대해 알아보겠습니다. 기본적으로 마우스 드래그를 통해 퍼즐조각을 움직여 퍼즐을 완성할

game-happy-world.tistory.com

질문 댓글 환영합니다

빠른 질문 답변 카카오톡 오픈톡 : open.kakao.com/o/gDlTpJpc

댓글