게임 프로그래밍/유니티 활용

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

레오란다 2023. 1. 1. 12:01
반응형

이번 글에서는 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에 따라 달라지기 때문에 자유롭게 변경이 가능합니다.

 

 

함께 보면 좋은 글

https://ugames.tistory.com/entry/%EC%9C%A0%EB%8B%88%ED%8B%B0-%ED%99%9C%EC%9A%A9-ScriptableObject-%EB%A1%9C-HP-Bar-%EB%A7%8C%EB%93%A4%EA%B8%B0-1

 

[유니티 활용] ScriptableObject 로 HP Bar 만들기 - #1

유니티는 ScriptableObject 라는 독특한 형태의 데이터 컨테이너를 제공합니다. 이 글에서는 유니티 공식 페이지에서 ScriptableObject 의 활용법으로 올라온 모듈형 디자인의 한 예제로 소개된 방식을

ugames.tistory.com

https://ugames.tistory.com/entry/%EC%9C%A0%EB%8B%88%ED%8B%B0-%ED%99%9C%EC%9A%A9-ScriptableObject-%EB%A1%9C-HP-Bar-%EB%A7%8C%EB%93%A4%EA%B8%B0-2

 

[유니티 활용] ScriptableObject 로 HP Bar 만들기 - #2

이 글은 "ScriptablObject 로 HP Bar 만들기 - #1" 에 이어서 작성하는 글입니다. ▶ PlayerObj 스크립트 작성 Hierarchy 창에서 Player 객체를 선택하고 PlayerObj 이름으로 새 스크립트를 생성합니다. PlayerObj 의

ugames.tistory.com

 

반응형