본문 바로가기
게임 프로그래밍/유니티 활용

[유니티 활용] ScriptableObject 를 이용한 스킬 시스템 만들기

by 레오란다 2023. 1. 1.
반응형

이번 글에서는 ScriptableObject를 활용해 캐릭터의 스킬 시스템을 구현해 보도록 하겠습니다. 구현 순서는 다음과 같습니다.

 

1. 무료 에셋 다운로드

2. Player 캐릭터 만들기

3. ScriptableObject 로 스킬 생성

4. 스킬 UI 연동

 

 

▶ 무료 에셋 다운로드

 

첫 번째 에셋은 무료 캐릭터 에셋입니다. 3D 캐릭터 모델과 여러 애니메이션이 포함되어 있습니다. 실습 예제로 사용하기에 부족함이 없어 보이는 에셋입니다.

 

 

RPG Tiny Hero Duo PBR Polyart | 3D 휴머노이드 | Unity Asset Store

Elevate your workflow with the RPG Tiny Hero Duo PBR Polyart asset from Dungeon Mason. Find this & other 휴머노이드 options on the Unity Asset Store.

assetstore.unity.com

 

두 번째 에셋은 스킬 아이콘 무료 에셋입니다. 이번 포스팅에 사용하기 좋은 아이콘이 포함되어 있어서 사용했습니다.

 

 

FREE - RPG Fantasy Spell Icons | 2D 아이콘 | Unity Asset Store

Elevate your workflow with the FREE - RPG Fantasy Spell Icons asset from Blink. Browse more 2D GUI on the Unity Asset Store.

assetstore.unity.com

위 두 개의 에셋을 다운로드 받아 Import 해 주세요.

 

 

▶ Player 캐릭터 만들기

첫 번째 받은 에셋에는 이미 Animator Controller 가 있습니다. 그런데 이것은 데모용으로 모든 Animation 을 차례대로 수행하도록 되어 있기 때문에 새로 만들어 사용하는 것이 좋습니다.

 

우선 Project 창에서 경로 [Assets > RPG Tiny Hero Duo > Prefab] 에 있는 "MaleCharacterPBR" 을 Hierarchy 창으로 드래그해서 객체를 생성하고 이름을 Player 로 변경합니다.

 

  ▷ 새 Animator Controller 만들기

  • Project 창의 Assets 폴더에서 마우스 우클릭 [Create > Animator Controller] 를 선택하고 이름을 HeroAnimator 로 변경한 다음 더블 클릭해서 Animator 창을 오픈합니다.
  • Project 창의 경로 [Assets > RPG Tiny Hero Duo > Animation > SwordAndShield] 로 이동합니다.
    • "Idle_Normal_SwordAndShield" 를 Animator 창으로 끌어다 놓아 state 를 생성하고 Insepctor 창에서 이름을 "Idle_Normal" 로 변경합니다.
    • "Attack03_SwordAndShield" 를 Animator 창으로 끌어다 놓고 이름을 "Skill_Stab" 으로 변경합니다.
    • "Skill_Stab" 을 선택하고 마우스 우클릭 [Make Transition] 선택 후 "Idle_Normal" state 를 선택해 연결합니다.
    • "Attack04_SwordAndShield" 를 Animator 창으로 끌어다 놓고 이름을 "Skill_Whirlwind" 로 변경합니다.
    • "Skill_Whirlwind" 를 선택하고 마우스 우클릭 [Make Transition] 선택 후 "Idle_Normal" 선택해 연결합니다.

Animator 설정
HeroAnimator 설정 결과

위의 과정을 완료했을 때 그림과 유사한 모양으로 되어 있어야 합니다.

 

  • 아래와 같이 새로만든 HeroAnimator 를 Player 객체에 있는 Animator > Controller 필드에 연결합니다.

 

  ▷ Player 스크립트

  • Player 객체를 선택하고 동일한 이름 (Player) 의 새 스크립트를 생성하고 다음의 코드 작성합니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
   Animator anim;

   private void Start()
   {
      anim = GetComponent<Animator>();
   }

   // UI 버튼에 의해 호출됩니다.
   // 인자로 넘어온 skill 정보에 따라 애니메이션을 플레이하고
   // damage 정보 만큼 피해를 입힙니다.
   public void ActivateSkill(SOSkill skill)
   {
      anim.Play(skill.animationName);
      print(string.Format("적에게 스킬 {0} 로 {1} 의 피해를 주었습니다.", skill.name, skill.damage));
   }
}
  • ActivateSkill 은 UI 스킬 버튼을 눌렀을 때 호출되는 함수입니다.

 

▶ ScriptableObject 로 스킬 생성

우선 Projects 창에서 Assets 에 Scripts 폴더를 생성해 줍니다. 이미지 아이콘은 다운로드 받은 무료 에셋인 [Assets > Blink > Art > Icons > Classes > Warrior > Barbarian] 에 있는 이미지를 사용했습니다.

 

  ▷ 기본 

  • Scripts 폴더에서 마우스 우클릭 [Create > C# Script] 로 새 스크립트를 만들고 SOSkill 로 이름을 변경한 후 다음과 같이 코드 작성
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu]
public class SOSkill : ScriptableObject
{
   public float damage;
   public float cool;

   public string animationName;
   public Sprite icon;
}
  • damage : 스킬 피해량
  • cool : 스킬 쿨타임
  • animationName : 스킬 사용시 재생할 animation state 이름
  • icon : 스킬 아이콘

 

  ▷ Stab (찌르기) 스킬 만들기

  • 마우스 우클릭 [Create > SO Skill] 을 선택하고 이름을 Stab 으로 변경하고 다음과 같이 설정합니다.

Stab 스킬 설정
Stab 스킬

 

  ▷ Whirlwind (회전베기) 스킬 만들기

  • 마우스 우클릭 [Create > SO Skill] 을 선택하고 이름을 Whirlwind 로 변경하고 다음과 같이 설정합니다.

Whirlwind 스킬 설정
Whirlwind 스킬

이처럼 ScriptableObject 를 상속해 만든 SOSkill 을 이용해 여러 개의 새로운 스킬 에셋을 만들어 사용할 수 있습니다.

 

 

▶ 스킬 UI 연동

  • Hierarchy 창에 [UI > Image] 를 생성하고 이름을 SkillSlot_1 로 변경 후 Button 컴포넌트 추가. 
  • RectTransform 을 다음과 같이 설정

  • 자식 객체로 [UI > Image] 를 생성하고 이름을 Cool 로 변경
    • 윈도우 그림판 등을 이용해 흰색의 작은 사각형 이미지를 만들고 Project 에 추가 후 Cool 객체의 Image 컴포넌트에 Source Image 로 연결 (ImageType: Filled 속성을 사용하기 위해)
    • Color 의 RGBA 를 모두 128 로 변경
  • SkillButton_1 객체를 선택하고 SkillButton 이름으로 새 스크립트 추가 
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class SkillButton : MonoBehaviour
{
   // ScriptableObject 로 생성한 스킬
   public SOSkill skill;

   // Player 객체 연결
   public Player player;

   // 스킬 이미지
   public Image imgIcon;

   // Cooldown 이미지
   public Image imgCool;

   void Start()
   {
      // SO Skill 에 등록한 스킬 아이콘 연결
      imgIcon.sprite = skill.icon;

      // Cool 이미지 초기 설정
      imgCool.fillAmount = 0;
   }

   public void OnClicked()
   {
      // Cool 이미지의 fillAmount 가 0 보다 크다는 것은
      // 아직 쿨타임이 끝나지 않았다는 뜻
      if (imgCool.fillAmount > 0) return;

      // Player 객체의 ActivateSkill 호출     
      player.ActivateSkill(skill);

      // 스킬 Cool 처리
      StartCoroutine(SC_Cool());
   }

   IEnumerator SC_Cool()
   {      
      // skill.cool 값에 따라 달라짐
      // 예: skill.cool 이 10초 라면
      // tick = 0.1
      float tick = 1f / skill.cool;
      float t = 0;

      imgCool.fillAmount = 1;

      // 10초에 걸쳐 1 -> 0 으로 변경하는 값을
      // imgCool.fillAmout 에 넣어주는 코드
      while (imgCool.fillAmount > 0)
      {
         imgCool.fillAmount = Mathf.Lerp(1, 0, t);
         t += (Time.deltaTime * tick);

         yield return null;
      }
   }
}
  • SkillButton 을 Inspector 에서 다음과 같이 설정

SkillButton 설정
SkillButton 설정

 

  • SkillSlot_1 을 선택하고 CTRL+D 를 눌러 복사 후 이름을 SkillSlot_2 로 변경
  • SkillSlot_2 객체를 선택하고 위와 같이 SkillButton 의 Skill 필드에 ScriptableObject 로 만든 Whirlwind 스킬을 연결

완성되었습니다. 다음은 실제 Play 했을 때 실행되는 화면입니다.

 

결과
실제 Play

 

이 방식의 장점은 ScriptableObject 로 생성한 스킬에 필요한 정보가 들어가 있기 때문에 확장이 쉽다는 것입니다. 또, UI 에 적용되는 스킬도 SkillButton의 Skill 필드에 연결된 ScriptableObject에 따라 달라지기 때문에 자유롭게 변경이 가능합니다.

 

 

 

반응형

댓글