프로그래밍/Spine

Spine2D 튜토리얼 03. 스파인을 가지고 C#에서 사용해 보자

windship 2017. 1. 29. 18:27

(출처 : http://blog.naver.com/ateliersera/220663774610)



* 초기 셋팅법 *


#region Inspector

[SpineAnimation]

public string runAnimationName;  //스파인은 String으로 동작을 찾게 되어있습니다. 스파인 프리펩에서 동작을 연결해 줍니다.

.

.

public AudioSource footstepAudioSource; //오디오 소스

#endregion


위와같이 사용할 애니메이션을 참조합니다. 이동이나 점프,공격..피격 등 필요한 만큼 작성해 줍니다. 


spineAnimationState.SetAnimation(0, runAnimationName, true);


등으로 사용이 가능합니다. spineAnimationState는 SkeletonAnimation 의 state 에 있는  정보 입니다. 그리고 skeleton 이라는 정보도 있습니다.

skeleton정보는 뼈대에 대한 정보로, X축으로 회전을 시키지 않고, skeleton.FlipX = true; 등을 사용하면 반전해서 사용할 수 있습니다. 


로테이션으로 스파인 유닛을 반전 시킬 경우, 쉐이더에 따라 라이트가 안받는 뒷면이 나오는 등의 문제가 발생 할 수 있습니다.


skeletonAnimation.state.SetAnimation(트랙(번호), 애니메이션이름(스트링), 루프(true/false) 로 3가지 속성이 있습니다. 보통 Idle이나, 이동 의 경우 루프가 true겠지만, 공격 등의 한번만 나와야 하는 모션의 경우에는 false 시켜야 합니다.


*스파인의 애니메이션 섞기 *

유닛이 이동 하면서, 눈을 깜빡이고 싶은데, 눈의 깜빡임은 좀 랜덤하게 나오고 싶다면?

유닛의 이동을 담당하는 애니메이션을 만들고, 이동 애니메이션에는 눈 깜빡임 애니메이션에대한 키값을 만들지 않습니다.  

다른 본들의 움직임에는 애니메이션을 만들지 않고, 눈깜빡이는 애니메이션만을 만듭니다.


위처럼 필요한 동작만을 만든 후, 두 트랙을 동시에 skeletonAnimation.state.SetAnimation 을 통해 플레이 할 경우, 자동으로 섞여서 나오게 됩니다.  매우 간단하지만, 애니메이션 제작 시 염두해 두고 만들어야 할 문제 입니다. 키값이 이미 존재한다면 무언가 하나의 애니메이션은 존재가 사라지는 현상이 발생합니다.




* 스파인 캐릭터의 기본 설정하기 * 

외부 키에 따라 액션을 설정하기 이전에, 모델에 대한 셋팅을 만들어 봅시다.

기본형은 예제에 있는 Spineboy입니다. 

.

.

public class SpineboyBeginnerModel: MonoBehaviour {


#region Inspector

[Header("Current State")]

public SpineBeginnerBodyState state;  //캐릭터의 상태를 위해 만들어진 헤더 입니다. 

public bool facingLeft;   // 좌우 반전을 위해 존재 합니다. 

[Range(-1f, 1f)]

public float currentSpeed; 


[Header("Balance")]

public float shootInterval = 0.12f;  //총 발사의 딜레이를 위한 값 입니다. 

#endregion


float lastShootTime;

public event System.Action ShootEvent; 



// 여기 아래부분은 점프, 발사, 이동을 시도하는 루틴 부분 입니다.

#region API

public void TryJump () {

 StartCoroutine(JumpRoutine());  //코루틴으로 점프 루틴을 돌렸습니다.

}


public void TryShoot () {

 float currentTime = Time.time;

      // 일정 시간이 지나야 슈팅 이벤트가 발생합니다.

 if (currentTime - lastShootTime > shootInterval) {

  lastShootTime = currentTime;

  if (ShootEvent != null) ShootEvent(); // Fire the "ShootEvent" event.

 }

}


public void TryMove (float speed) {

 currentSpeed = speed; // show the "speed" in the Inspector.


 if (speed != 0) {

  bool speedIsNegative = (speed < 0f);

  facingLeft = speedIsNegative; 

 }

 //점프중이 아닐때만 이동을 시도합니다. 

 if (state != SpineBeginnerBodyState.Jumping) {

 state = (speed == 0) ? SpineBeginnerBodyState.Idle : SpineBeginnerBodyState.Running;

 }


}

#endregion

//여기까지가 시도 하는 루틴 부분


IEnumerator JumpRoutine () {

 if (state == SpineBeginnerBodyState.Jumping) yield break; // 점프중일때는 점프를 시도하지 않습니다. 


 state = SpineBeginnerBodyState.Jumping;

 yield return new WaitForSeconds(1.2f); 

 state = SpineBeginnerBodyState.Idle;

 }


}


//state 를 나눠 줍니다. 현재는 세가지.  대기 상태와 뛰기, 점프 상태 입니다. 

public enum SpineBeginnerBodyState {

 Idle,

 Running,

 Jumping

}


//여기까지가 스파인 유닛에 붙는 스크립트 입니다. 간단하게 대기/이동/점/슈팅 으로 되어 있습니다. 이동이나 점프중에 슈팅이 가능한 구조 입니다.

-------------------------------------------------------------------------------------------

* 컨트롤 부분의 스크립트 예제 * 

public class SpineboyBeginnerInput : MonoBehaviour {


 #region Inspector

 public string horizontalAxis = "Horizontal";

 public string attackButton = "Fire1";

 public string jumpButton = "Jump";


 public SpineboyBeginnerModel model;



//OnValidate()가 사용되었는데, 값의 유효성을 검사할때 추가로 사용자 지정 프로세스를 수행하는 메소드 입니다. CollectionBase.OnValidate메소드 입니다.

//Start() 라거나 Awake()에 넣지 않고 값의 유효성 검사를 위해 OnValidate()를 사용했습니다.

 void OnValidate () {

  if (model == null)

   model = GetComponent<SpineboyBeginnerModel>();

 }

 #endregion


 void Update () {

  if (model == null) return;


  float currentHorizontal = Input.GetAxisRaw(horizontalAxis);

  model.TryMove(currentHorizontal);


  if (Input.GetButton(attackButton))

   model.TryShoot();


  if (Input.GetButtonDown(jumpButton))

   model.TryJump();

 }

}


//유닛의 컨트롤 부분에 있어서는 키를 받게 되면 해당 오브젝트에게 이동이나 슈팅, 점프를 시도하도록 명령만 보내는 구조 입니다.  흔히 말하는MVC구조

[출처] Spine2D 튜토리얼 03. 스파인을 가지고 C#에서 사용해 보자.|작성자 세라프