[Spine] 갖춰진 Skin의 slot속 Data갱신

·2024년 8월 12일
0

Unity

목록 보기
10/11
post-thumbnail

스파인으로 작업된 애니메이션의 slot들에 접근하여 원하는 시점에 맞는 이미지 출력을 하고자 한다.

▶️ spine을 unity로

아트 리소스를 일단 유니티에 가져오자.

정상적으로 불러와졌다면 spine atlas asset에 올바른 atlas region이 연결되어 있을 것이다.
여기 있는 목록들의 name을 활용하여 데이터를 갱신하게 된다.

여기서 slot, attachment, region이라는 개념이 나오게 되는데,

  • slot : 어느 부위
  • attachment : slot이 담은 정보중 부착 데이터를 담을 공간
  • region : 실제 데이터

라고 이해하게 되었다. 예시를 들자면 포인터라고 생각하면 쉽다.

사실 여기서 좀 다른 부분은 slot은 attahment라는 정보 하나만을 담은 것이 아니라 배열 형태의 포인터라면 더 맞는 예시가 될 거같다.
(사실 야매로 이해한 것이기 때문에 정확한 개념 설명이 아닐 수 있다.)

Player의 애니메이션 제어를 위해 자식으로 animation 객체를 생성해주고 여기서 스크립트를 컴포넌트로 붙여주는데

동시에 spine skeletonAnimation도 같이 붙여준다. 기존 유니티 애니메이션 방식으로 따지면 Animator라고 생각하면 된다. 그러면 skeletionData Asset을 연결해야하는데 여기서 처음에 불러온 6개의 파일 중 dataAsset을 넣으면 된다.

▶️ 코드 구현

이 개념을 가지고 이제 코드에 접근할 것이다. 스파인을 코드에서 사용하기 위해선 아래의 참조 선언이 필요하다.

using Spine;
using Spine.Unity;
using Spine.Unity.AttachmentTools;

원하는 region을 찾기 위해서는 atlas 파일이 필요하기에 파일을 담을 변수를 선언해서 사용해주고 적용할 현재 플레이어의 애니메이션 정보를 가져오기 위해 SkeletonAnimationSkeletonRenderer도 같이 선언해준다.

public SpineAtlasAsset atlasAsset;

Atlas atlas;
SkeletonAnimation skeletonAnimation;
SkeletonRenderer skeletonRenderer;

void Awake()
{
	skeletonRenderer = GetComponent<SkeletonRenderer>();
	skeletonAnimation = GetComponent<SkeletonAnimation>();
}

renderer는 아까 추가한 dataAsset에 있는 것을 정의를 보면 알 수 있기에 따로 컴포넌트 추가가 필요없다는 것을 확인해준다.

모든 준비가 완료되었다면 이제 어느 부위의 데이터를 바꿀 것인지 원하는 slot을 FindSlot(name)으로 찾아준다.

void ChangeSkinSlot(Direction _region)
{
	atlas = atlasAsset.GetAtlas();
	float scale = skeletonRenderer.skeletonDataAsset.scale;
    // 적용하고자 하는 유니티 속 크기에 맞추기 위해 현재 player에 적용된 크기 정보를 가져온다.

	Slot slot;
	AtlasRegion region;

	slot = skeletonRenderer.skeleton.FindSlot(attachments[1].slot);
	// 현재 플레이어의 애니메이션에서 어떤 부위를 바꿀 것인지 지정한다.

스파인 에셋을 위한 변수는 인스펙터에서 보는 것을 지원하므로 원하는 slot이나 데이터 지정을 편하게 할 수 있다.

[SpineSlot] public string slot; 
[SpineAtlasRegion] public string region;

내가 원하는 attachments[1].slot은 클래스 형태로, 자료 지정을 편하게 하기 위해 선언한 변수이다.

이렇게 인스펙터창에서 자료형에 맞는 데이터 목록을 보여준다!
물론 모든 스파인 에셋은 string으로 찾기에 쌩 문자열로 지정해도 되긴 하지만 안정적이게 해당 방법으로 하는 것을 추천한다.

나는 이동하거나 마우스 조작에 따라 원하는 방향에 맞춰 얼굴 방향이 바뀌는 결과를 원하기에 기존 정면에서 플레이어의 상황에 따라 원하는 region을 찾고 지정한 slot의 attachment에 갱신하는 방식으로 코드를 구성했다.

	switch (_direction)
	{	
		case Direction.FRONT_R:
			region = atlas.FindRegion(_direction.ToString() + "/FACE");
			break;
		default:
			region = atlas.FindRegion(_direction.ToString() + "/Face");
			break;
	}

	Attachment originAttachment = slot.Attachment;
	slot.Attachment = originAttachment.GetRemappedClone(region, true, true, scale);
}

초반에는 아래처럼 했다. 하지만 특정 방향에서만 에러가 발생해 알고 봤더니 region의 문자열이 한 방향만 FACE라 찾지 못해 뜬 에러였다.

고로 find할 때는 꼭꼭 region의 이름을 잘 확인하거나, 아예 원하는 region을 변수에 담고 그것을 사용하는 것도 방법이다.

  • atlas 정보는 디자이너와 협업해서 네임 컨벤션을 정하는 것도 좋은 방법 같다.
region = atlas.FindRegion(_direction.ToString() + "/Face");

Attachment originAttachment = slot.Attachment;
slot.Attachment = originAttachment.GetRemappedClone(region, true, true, scale);

그리고 region 데이터를 갱신하는 함수 GetRemappedClone를 살펴보면,

기본 사이즈로 디폴트 구성이고, 원하는 사이즈를 위해서는 3번째 불리언 값을 true로 바꿔주고 스케일 인자를 넘겨주면된다.

추가로 다른 애니메이션과 섞이지 않게 분기 처리를 철저하게 하자.
나는 idle과 run의 상태에서만 얼굴 방향 변경 처리에 맞춰 코드를 구성했지만 방향 QA하던 도중 dash일때도 순간적으로 해당 함수를 실행해 에러가 발생해서 조건문을 따로 처리해줬다.

▶️ 결과!

원래는 마우스를 따라가지 않고 그냥 걷는 방향으로 얼굴이 full skin 고정으로 갖춰져 있었다.

profile
할 수 있는 최선을 다하는 클라이언트 개발자랍니다 (❁´◡`❁)

0개의 댓글

관련 채용 정보