이번 글에서는 ScriptableObject를 활용해 캐릭터의 스킬 시스템을 구현해 보도록 하겠습니다. 구현 순서는 다음과 같습니다.
1. 무료 에셋 다운로드
2. Player 캐릭터 만들기
3. ScriptableObject 로 스킬 생성
4. 스킬 UI 연동
▶ 무료 에셋 다운로드
첫 번째 에셋은 무료 캐릭터 에셋입니다. 3D 캐릭터 모델과 여러 애니메이션이 포함되어 있습니다. 실습 예제로 사용하기에 부족함이 없어 보이는 에셋입니다.
두 번째 에셋은 스킬 아이콘 무료 에셋입니다. 이번 포스팅에 사용하기 좋은 아이콘이 포함되어 있어서 사용했습니다.
위 두 개의 에셋을 다운로드 받아 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" 선택해 연결합니다.
위의 과정을 완료했을 때 그림과 유사한 모양으로 되어 있어야 합니다.
- 아래와 같이 새로만든 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 으로 변경하고 다음과 같이 설정합니다.
▷ Whirlwind (회전베기) 스킬 만들기
- 마우스 우클릭 [Create > SO Skill] 을 선택하고 이름을 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 에서 다음과 같이 설정
- SkillSlot_1 을 선택하고 CTRL+D 를 눌러 복사 후 이름을 SkillSlot_2 로 변경
- SkillSlot_2 객체를 선택하고 위와 같이 SkillButton 의 Skill 필드에 ScriptableObject 로 만든 Whirlwind 스킬을 연결
완성되었습니다. 다음은 실제 Play 했을 때 실행되는 화면입니다.
이 방식의 장점은 ScriptableObject 로 생성한 스킬에 필요한 정보가 들어가 있기 때문에 확장이 쉽다는 것입니다. 또, UI 에 적용되는 스킬도 SkillButton의 Skill 필드에 연결된 ScriptableObject에 따라 달라지기 때문에 자유롭게 변경이 가능합니다.
함께 보면 좋은 글
'게임 프로그래밍 > 유니티 활용' 카테고리의 다른 글
[유니티 활용] ScriptableObject 를 이용한 아이템 관리 (0) | 2023.01.04 |
---|---|
[유니티 활용] ScriptableObject 와 Reflection 을 이용한 간단한 버프 시스템 만들기 (1) | 2023.01.03 |
[유니티 활용] ScriptableObject 로 HP Bar 만들기 - #2 (3) | 2022.12.30 |
[유니티 활용] ScriptableObject 로 HP Bar 만들기 - #1 (1) | 2022.12.29 |
[유니티 활용] StateMachine 과 몬스터 AI (2) | 2022.12.26 |
댓글