Turn Based RPG Game Wiki - UAVisonline/Portfolio GitHub Wiki

턴제 기반 육성 RPG 게임 제작 프로젝트

해당 게임은 교양 과목 : 모바일게임프로그래밍에 대한 학기 과제로 제작한 프로젝트이다. 게임은 다양한 특성을 얻고 이를 극대화하는 방향으로 캐릭터를 육성하는 방식으로 진행되며, 턴제 전투를 진행하는 것으로 사용자는 자신의 캐릭터가 효과적으로 육성했는지 확인할 수 있으며 이러한 과정 속에서 재미를 얻는 것을 목표로 하고 있다.

해당 프로젝트는 2022년 10월부터 기획 및 제작을 진행하였으며 2022년 12월 개발 완료, 이를 발표하는것으로 완료된 프로젝트이다.

게임 내 그래픽 및 음악파일은 이전에 구매했던 Asset을 활용하는 방식으로 해결하였으며, 그 외 부분은 직접 제작하는 방식으로 프로젝트 개발을 진행하였다.

해당 위키에서는 프로젝트에 대해 아래와 같은 항목들을 통해서 설명하고자 한다.

  • Observer 패턴을 통한 특성 구현 및 발동

  • 게임 내 아이템 및 인벤토리 시스템 제작

  • 턴제전투 및 적에 대한 구현

1. Observer 패턴을 통한 특성 구현 및 발동

해당 위키에서 서술하는 게임 프로젝트는 플레이어의 능력치를 Amulet이라 칭하는 특성을 통해 변화시킬 수 있다.

그리고 프로젝트 내에는 20개이상 고유 특성들이 존재하는데, 이를 어떻게 구현하였는지 아래 소항목 2개를 통해 설명하고자 한다.

1. 다양한 특성을 어떻게 유연하게 구현할 것인가? (Inheritance 및 Polymorphism)

해당 게임 내 특성은 플레이어에게 특별한 능력을 부여하거나, 공격력 및 방어력과 같은 특정 수치를 올리는 식으로 작동한다. 또한 이러한 특성들은 획득하는 즉시 발동되거나, 특정 타이밍마다 발동이 되는 식으로 이루어진다.

이러한 부분을 고려한 결과, 모든 특성들은 아래와 같은 속성 및 기능을 공유하게 되며 이를 아래 BaseAmuletScript로 정의하였다.

BaseAmuletScript

속성
특성에 대한 정보 : 코드, 이름, 설명문, 이미지, 소지제한숫자 (Unity ScriptableObject로 관리)
해당 특성이 발동될 상황 (enum 열거체로 관리 : 9가지 값으로 정의)

기능 (전부 가상함수로 설정)
특성획득 함수 (OnAcquire) : 플레이어에게 해당 특성을 새로 얻었음을 알려줌
특성소멸 함수 (OnDismiss) : 플레이어가 해당 특성을 잃어버렸다는 것을 알려줌
특성기능 함수 (OnFunction) : 특성 자체의 기능이 서술될 함수 (인자로 enum 변수를 받음)

그 외 Unity에서 기본 지원하는 MonoBehaviour클래스의 OnEnable(오브젝트 생성 시 자동 발동)함수를 이용하여 소지한 여러 특성들을 관리하는 것이 가능하다. (이는 아래 1-2번 항목에서 자세히 서술한다)

위 부모 클래스를 상속하여 자식 클래스를 만들고, 속성값을 새로 할당하는 것 및 가상함수를 오버라이딩하는 것으로 아래 2가지 Script와 같이 원하는 특성을 구현할 수 있다.

public class Amulet_002 : BaseAmuletScript (002번 특성 : 획득 즉시 발동되며 다시 발동되지 않음)
{
    public override void OnAcquire() [부모클래스에 OnAcquire 함수를 오버라이딩함 -> 획득 즉시 아래 내용을 실행]
    {
        PlayerManager.playerManager.spec.amulet_max_hp += 25; [플레이어의 체력 최대치를 25 올린다]

        base.OnAcquire(); [부모클래스 OnAcquire도 발동하여 플레이어가 해당 특성을 새로 얻었음을 고지]
    }

    public override void OnDismiss() [부모클래스에 OnDismiss 함수를 오버라이딩함 -> 특성을 잃어버리는 경우 아래 내용을 실행]
    {
        PlayerManager.playerManager.spec.amulet_max_hp -= 25; [플레이어 체력 최대치를 25 내린다]

        base.OnDismiss(); [부모클래스 OnDismiss도 발동하여 해당 특성을 잃어버렸음을 고지]
    }
} => 플레이어의 체력 최대치를 25만큼 즉시 올리는 특성
public class Amulet_048 : BaseAmuletScript (048번 특성 : 특정 타이밍이 올 때마다 발동되는 경우)
{
    public override void OnFunction(Amulet_timing timing) [열거체 변수인 timing을 인자로 받아옴]
    {
        if (timing == Amulet_timing.after_attack) [인자가 공격후 열거체와 같은 경우]
        {
            if(DungeonManager.dungeonManager.ret_player_attack() == attack_type.physical) [플레이어의 공격이 물리공격인 경우]
            {
                int value = DungeonManager.dungeonManager.ret_current_damage(); [현재 데미지 수치를 받아옴]

                value = Mathf.RoundToInt(value * 0.03f); [여기에 대해 0.03을 곱함]

                if(value <= 0) [위 값이 0이하이면]
                {
                    value = Random.Range(0, 2);  [값을 0~2에서 랜덤으로 맞춤]
                }

                DungeonManager.dungeonManager.heal_player_fixed(value); [value값 만큼 체력을 회복]
            }
        }
    }
} => (플레이어가 적에게 물리공격을 한 경우, 데미지수치에 3%만큼 체력을 회복하는 능력을 가진 특성을 제작)

2. 수많은 특성은 어떻게 관리하고 발동시킬 것인가? (Observer패턴을 통한 subscribe/publish)

게임 내 얻은 모든 고유 특성을 플레이어는 특정 상황을 위해 관리할 수 있어야 하며, 이를 위해서는 아래 3가지 기능이 플레이어 내 구현되어야 한다.

(1) 특성등록작업 : 게임 내에서 새로 획득한 특성을 플레이어가 관리 가능한 상태로 만드는 작업

(2) 특성해제작업 : 더 이상 사용할 수 없는 특성에 대해 관리 불가능한 상태로 만드는 작업

(3) 특성동작작업 : 플레이어가 소유한 특성 중 일부 특성들만 동작하도록 하는 작업

이러한 작업은 플레이어에 대한 정보를 관리하는 PlayerManager 코드 내 Observer 패턴로 구현되었으며, 타 스크립트는 PlayerManager에 접근해 특정 함수를 실행하는 것으로 위 작업을 실행할 수 있다.

  1. 특성 등록 [insert_amulet 및 insert_detail_amulet 함수]

  2. 특성 해제 [dismiss_amulet 및 dismiss_detail_amulet 함수]

  3. 특성 동작 [function_amulet 함수]

2. 게임 내 아이템 및 인벤토리 시스템 제작

3. 턴제전투 및 적에 대한 구현

⚠️ **GitHub.com Fallback** ⚠️