게임 개발 공부 기록

52일차 - Abyss_Slayer 최종 팀 프로젝트 2 (스킬 데이터 구조 구성)

00lwt 2025. 4. 7. 21:54

▶▷ 스킬 데이터 관리

타겟팅 정보, 스킬 종류, 실행 메소드를 담은 추상화 클래스, 실제 스킬 로직을 담은 ScriptableObject를 스킬의 공통되는 요소를 담는 SkillData에 담는 구조이다.

직업의 폴더 구조는 위와 같다.
각 스킬별로 폴더를 나누어 해당 키에 대응하는 스킬마다 데이터는 3개가 들어간다.

 

ArcherSkill_x.cs

[CreateAssetMenu(menuName = "Skill/Archer/Archer_x")]
public class ArcherBasicAtk : SkillExecuter
{
    public override void Execute(Character user, Character target, SkillData skillData)
    {
        // 스킬 로직 작성
    }
}

 

TargetingData.cs

/// <summary>
/// 스킬이 어떤 대상에게, 어떤 방식으로 적용되는지 정의하는 ScriptableObject.
/// 예: 단일 대상, 범위, 아군/적군, 자기 자신 포함 여부 등.
/// </summary>
[CreateAssetMenu(menuName = "Skill/Base/TargetingData")]
public class TargetingData : ScriptableObject
{
    [Header("타게팅 조건")]
    public bool requiresTarget;     // 대상 지정이 필요한지 (false면 자동 발동)

    [Header("적용 범위")]
    public bool affectEnemies;      // 적에게 효과
    public bool affectPlayers;      // 아군에게 효과
    public bool includeSelf;        // 자기 자신 포함 여부

    public bool isArea;             // 단일 or 범위
    public float range;             // 시전 거리 (공격 스킬)
    public float areaRadius;        // 범위 반경 (힐 or 버프)
}

 

SkillData.cs

// 스킬의 공통으로 필요한 데이터를 저장하는 ScriptableObject.
[CreateAssetMenu(menuName = "Skill/Base/SkillData")]
public class SkillData : ScriptableObject
{
    [Header("기본 정보")]
    public string skillName;                // 스킬명
    public string description;              // 설명
    public int manaCost;                    // 마나 소모량
    public float cooldown;                  // 쿨타임
    public bool canMove;

    [Header("시각적 요소")]
    public Sprite icon;                     // 스킬 아이콘
    public string animationTrigger;         // Animator에서 호출할 트리거 이름
    public GameObject effectPrefab;         // 이펙트 프리팹

    [Header("스킬")]
    public SkillCategory category;			// 스킬 종류
    public SkillExecuter executer;			// 스킬 실행 클래스
    public DamageType damageType;			// 데미지 타입 (물리, 마법)
    public EvasionType evasionType;			// 회피 종류 (대쉬, 텔포)

    [Header("타겟팅")]
    public TargetingData targetingData;     // 타겟팅 데이터

    public void Execute(Character user, Character target)
    {
        executer?.Execute(user, target, this);
    }
}

인스펙터에서는 이런식으로 할당이 된다.
스킬의 종류, 데미지 타입, 대쉬 타입은 Enum으로 작성하여 인스펙터 상에서 드롭으로 편하게 고를 수 있도록 하였다.
이렇게 해서 생성된 SkillData는 A, S, D 등 각 키에 해당되는 스킬이고 이 스킬들을 모아 스킬셋으로 만들어 관리할 예정이다.

스킬 데이터를 관리하는 방식을 CSV나 JSON 대신 ScriptableObject를 채택한 이유
스킬의 가짓 수가 그리 많지 않아 직관성을 우선으로 두었고 다른 팀원들이 보기에도 직관적이며 수치 변경 등의 작업을 인스펙터 상에서 하기 편하게 만들기 위함이다.

내일은 스킬셋을 구현해서 각 키별로 나누어진 스킬들을 모아서 관리해보고 테스트용으로 궁수의 스킬 로직을 간단하게 작성해 볼 예정이다.

 

▶▷ 알게된 점

게임의 규모가 크지 않아 데이터의 수가 그리 많지 않을 경우 ScriptableObject를 사용해서 직관적으로 구성하는 것은 좋은 방법.
enum도 마찬가지로 타입의 가짓 수가 많이 않을 경우 ScriptableObject와 같이 사용하면 잘 어울리기 때문에 사용하기 좋음.