구현요소
위와 같은 케릭터 선택창을 만드는게 목표입니다. 첫 번째로 위 케릭터 선챙 창 그리드를 만들어야합니다.
두 번째로는 커서가 캐릭터 그리드의 요소들을 감지하여 특정 행동을 해야합니다.
세 번째로는 스크린 아래부분에 플레이어 캐릭터 슬롯을 만들어야 합니다.
네 번째로는 토큰을 케릭터에 던져 선택하는 기능이 필요합니다.
분석
믹스 앤 잼 튜토리얼(링크)은 두 번째 따라해보니 저자가 제공해주는 유니티 프로젝트를 가지고 차례대로 분석하는게 좋아보입니다. 이 사람이 타겟 씬을 어떻게 분석하여 클론 프로젝트를 마무리 했는지 전체적인 흐름을 자세히 살펴보는 방식으로 이해해보겠습니다. 그렇게 큰 흐름만 파악하고 기록해두고 나중에 써먹는 것입니다.
우선 저자는 클론 프로젝트를 진행할 타겟 씬을 선정했습니다. 타겟 씬은 위 유튜브 영상의 캐릭터 선택창입니다. 여기서 저자는 참조할 레퍼런스(타겟 씬)의 이미지를 가져와 활용합니다.
참조할 레퍼런스 이미지를 카메라 화면에 맞춰 깔아주어 밑그림이 되도록 해줍니다. (스케치)
그리고 레퍼런스 이미지를 활용해 그대로 비슷하게 만듭니다. (각종 이미지 파일은 튜토리얼 저자의 프로젝트 파일에서 가져왔습니다) 그리고 이 캐릭터셀을 프리펩으로 만들어 저장합니다. 그리고 이 캐릭터셀을 하나의 데이터로 저장하여 활용하기 위해 저자는 유니티 ScriptableObject 를 이용합니다.
*스크립터블 오브젝트란
모든 에셋(메터리얼, 애니메이션 클립 등)들은 UnityEngine.Object의 자식클래스로서 존재하게 됩니다. 여기서 저희도 독자적인 에셋을 만들기 위해서 이 오브젝트의 자식클래스를 하나 만들어내고 싶은데 일반적으로 이 방식이 금지됩니다. 이를 해결하기 위해 유저는 Unity의 시리얼라이즈 구조를 이용하여, ScriptableOjbect를 이용하여 독자적인 에셋을 만들어야합니다.
스크립터블 오브젝트는 대량의 데이터를 보관할수 있는 데이터 보관함 역할을 합니다. 스크립터블 오브젝트를 이용하는 이유는 값의 사본이 생성되는 것을 방지하고 변경되지 않는 데이터의 프리펩에 한하여, 기존에 인스턴스 방식으로 데이터 자체에 대한 사본을 만드는 것이 아닌 단지 메모리에 스크립터블 오브젝트의 데이터 사본만을 저장하여 이를 참조하는 방식으로 사용되기 때문에 더 효율적이기 때문입니다.
그래서 이러한 방식으로 아래처럼 하스스톤의 카드들을 구성할수도 있습니다.
스크립터블 오브젝트를 상속한 Card 클래스에 카드의 정보를 받도록해주고, 이 데이터 파일에 에셋으로 접근하여 좌측 사진과 같이 데이터를 넣어줄수 있습니다. 이를 오른쪽 화면에서처럼 card 를 참조하는 형식으로 쉽게 데이터 세팅이 가능합니다.
그러면 데이터에 케릭터의 이미지 파일과 이름을 저장해놓고 위와 같이 동적으로 케릭터를 설정할수있습니다. 여기서 몇가지 세팅을 해야하는데요. 캐릭터 이미지마다 다른 pivot 위치를 적절하게 통일시켜야합니다. 캐릭터 선택 창에서 알맞게 보일 수 있게요.
위와 같은 스프라이트 이미지의 인스펙터에 접근하여 스프라이트 에디터로 들어갑니다. 그러면 피봇을 따로 설정할수있습니다. 적절한 위치로 스프라이트의 피봇을 설정하여 캐릭터 화면에서 적절히 잘보일수 있도록 해줍니다.
//화면에 보일 artwork의 피봇값을 uiPivot(UI에 보이는 피봇)으로 설정해야한다.
//uiPivot은 텍스쳐 피봇과 다르다. UI에선 스케일로 피봇을 책정하는데, 텍스쳐는 픽셀단위라 화면이 넓을 경우 피봇을 변경해도 UI에서 티가 안난다~
//고로 텍스쳐의 피봇위치를 스케일로 변환해야하는데, 이는 각 피봇에서 텍스쳐의 가로세로 길이를 나누면 스케일 피봇이 나온다.
Vector2 pixelSize = new Vector2(artwork.sprite.texture.width, artwork.sprite.texture.height);
Vector2 pixelPivot = artwork.sprite.pivot;
Vector2 uiPivot = new Vector2(pixelPivot.x / pixelSize.x, pixelPivot.y / pixelSize.y);
artwork.GetComponent<RectTransform>().pivot = uiPivot;
artwork.GetComponent<RectTransform>().localScale *= characterInfo.artworkScale;
하지만 텍스쳐에만 피봇설정을 해준다면 UI 상에선 크게 변화가 없습니다. 왜냐하면 UI (캔버스 내 피봇) 에선 피봇의 계산이 스프라이트 이미지에서의 피봇 계산과 다르기 때문입니다. UI는 스케일로 피봇을 계산하죠. 그러므로 위와 같이 텍스쳐 피봇 위치를 스케일로 변환하여 대입시켜줍니다. 추가로 캐릭터마다 크기가 다르므로 artworkScale라는 변수를 통해 이미지의 크기를 조정할수 있게 했습니다.
그럼 2편에서 상호작용을 위한 이벤트를 더 추가해보겠습니다.