XR플밍 - (주말작업) 개인 프로젝트 3.2일차(6/1)

이형원·2025년 6월 1일
0

XR플밍

목록 보기
91/215

0.들어가기에 앞서
이제쯤이면 게임의 완성도가 어느 정도 되어 있어야 한다. 공휴일을 포함해 3일 정도가 남았지만 필요한 기능을 구현하기에는 시간이 여유롭지는 않았다.

1. 3.2일차 작업 정리

씬 추가 및 기능 구현과 더불어, 버그 수정에 많은 시간을 투자했다.
그래도 어느 정도의 게임으로서의 틀은 잡혀가고 있는 것 같다.

<버그 픽스>

  • 스펠 데미지 버그 2차 수정, 이젠 데미지가 중첩해서 들어가는 버그를 해결한 것 같다
  • 몬스터의 추격과 관련된 버그 수정
    • 몬스터가 발 아래에 및 위에 있는 유저도 인식하는 버그
    • 몬스터가 절벽에 떨어지는 위치에 서 있는데도 쫓아오는 버그

<맵 구현>

  • 타이틀 씬
  • 스테이지 2 씬 (갈림길)
  • 스테이지 3-1 씬
  • 스테이지 3-2 씬
  • 스테이지 4 씬 (미완성)

<기능 구현>

  • 씬 체인저
  • 씬 체인저를 이용한 포탈 트리거
  • 몬스터 피격시 짧게 스턴 기능 및 죽음 애니메이션 구현
  • 체력 포션 및 마나 포션의 추가
  • 몬스터를 죽일 시 낮은 확률로 체력 포션이나 마나 포션 중 하나가 떨어지며, 체력 포션과 마나 포션의 회복 수치는 특정 범위 내의 랜덤한 수치로 회복하는 것으로 설정
  • 플레이어의 마나 스텟 추가 및 스펠 사용시 마나 소모
  • 플레이어 UI 작업 마무리 및 프로필 이미지 추가
  • 플레이어 스펠 데미지 - 차지 시간에 따른 데미지 증가 시스템 추가
  • 플레이어 스펠 차지 시간 표시 UI 추가(그림 게이지)

<스샷 모음>

  • 타이틀 씬

    (AI 생성 이미지 고마워요)

  • 인게임 씬

2. 문제의 발생과 해결과정

2.1 MonsterState에서의 문제점

MonsterState는 상태패턴을 이용해 구현한 몬스터의 행동 양상이다. 따라서 몬스터의 AI 성능은 이 State를 얼마나 잘 짜느냐에 따라 성능이 달려 있었다.

이전부터 계속 겪었던 문제는 몬스터가 너무 열심히 추격해 와서 몬스터가 아래로 추락하는 현상을 목격했다는 것이다.
실제로 이것 때문에 몇 시간이나 MonsterState를 붙잡고 리팩토링을 하고 코드 수정과 테스트를 반복해야 했다.
결과적으로는 현재 몬스터가 추락하지 않도록 세팅하는 데 성공했고, 그 원인조차 Ray를 잘못 쏘아서 판정이 잘못된 경우란 걸 알게 되었다.

이와 같은 점을 미루어 보았을 때 느낀 것은, 이와 같이 특정 상태에서 다른 상태로 변화하는 과정을 로직으로 짤 때, 구조를 미리 짜 놓아야 한다는 것을 느꼈다. 그리고 Play 방식을 섞어쓰는 경우 디버깅이 참 어렵다는 것을 느꼈고.

결론 : 몬스터 동작 로직을 짤 때 미리 구조를 짜 놓고 만드는 것이 좋으며, 짜 놓은 구조 또한 기본적인 도식을 남겨놓도록 하자.

2.2 싱글톤 매니저들의 관리의 어려움과 테스트

각 스테이지를 만들고 테스트하는 과정에서 느낀 거지만, 각 맵을 테스트하기 위해서는 결국 게임매니저가 필요했다. 그런데 이렇게 각 스테이지에 싱글톤 매니저들을 붙여놓고 나중에 통째로 한 번에 플레이하려고 하면 그대로 터져버린다.

최종적으로 타이틀 씬에서부터 최종 씬까지 플레이할 때에는 씬 하나에만 싱글톤을 남겨 놓고 다시 작업해야 하는 어려움이 있었다. 이게 아무래도 싱글톤의 단점이라 할 수 있겠다.

2.3 랜덤의 사용

이전부터 랜덤 요소에 대한 사용을 해 보고 싶었지만, 이번 기회에 사용해보게 되었다.

몬스터는 낮은 확률로 포션을 떨구게 했으며, 그 떨군 포션 또한 랜덤한 수치로 회복율이 결정되는 구조로 설계하였다. 코드는 아래와 같이 작성했다.

  • Monster에서 아이템 드랍
private void DropPotion()
{
    if(IsDead)
    {
        int rand = Random.Range(0, 10);
        if(rand == 7)
        {
            Instantiate(m_potions[0], transform.position, Quaternion.identity);
        }
        if(rand == 8)
        {
            Instantiate(m_potions[1], transform.position, Quaternion.identity);
        }
    }
}
  • 아이템의 수치 결정
using UnityEngine;

public class HealthPotionCreater : PotionCreater
{
    private int m_status;

    private void Awake() => Init();

    private void Init()
    {
        m_status = Random.Range(1, 4);
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.CompareTag("Player"))
        {
            if (GameManager.Instance.GetCurHP() == GameManager.Instance.GetMaxHP()) return;
            Recover();
            gameObject.SetActive(false);
        }
    }

    public override void Recover()
    {
        GameManager.Instance.RecoverHp(m_status);
    }
}

3. 수정해야 할 점과 과제

3.1 (수정) 몬스터 로직의 추가 버그 사항 확인 및 리팩토링 과정

코드가 슬라임 코드로 작성되어 있어서 NormalMonster 코드로 통일할 필요사항이 있음

3.2 일시정지 UI, 게임 오버 UI, 게임 클리어 UI

일시 정지 메소드에 대한 부분이 필요하고, 게임 오버와 게임 클리어에 대한 처리가 필요하다.

3.3 스코어 시스템 및 밸런싱

몬스터를 잡으면 스코어가 오르도록 되어 있으나, 아직 이걸 인게임으로 반영하지 않았다.
또한 몬스터의 종류에 따른 스코어 점수 차등 지급 및 밸런싱 작업이 필요하다.

3.4 (도전)스펠 차징 시 시간 느려짐 구현

애초에 이런 주제로 프로젝트를 시작한 것 자체가 사실은 젤다의 전설 야생의 숨결/왕국의 눈물의 활 조준 시스템을 만들고 싶다는 생각 하나 때문이었다.

(이와 같이 활을 조준하면 시간이 느려지면서 조준할 시간을 주고, 스태미나를 소모하는 만큼 시간을 느리게 하는 시스템이 있기는 한데...)
가능하다면 구현해 보고 프로젝트 기간 안에 구현을 못하더라도 고민해보자.

3.5 (도전) 보스 몬스터 구현

게임 자체가 아직은 단조롭다 보니 시간이 남으면 보스 몬스터 구현을 해 보는 것도 나쁘지 않을 것 같다.

profile
게임 만들러 코딩 공부중

0개의 댓글