One_KWS

게임 개발 일지 #12 - 다음 스테이지로 넘어가기 본문

게임 개발

게임 개발 일지 #12 - 다음 스테이지로 넘어가기

One-Kim 2023. 4. 3. 23:40

생성된 몬스터를 다 잡으면 다음 구역으로 넘어갈 수 있다. 그래서 몬스터를 전부 잡으면 다음 층으로 넘어갈 수 있는 포탈을 활성화 시키고 플레이어를 다음 구역으로 이동시키는 기능을 구현했다.

 

Portal 만들기 

맵 한쪽에 다음 구역으로 갈 수 있는 문을 만들었다. 그냥 문만 놓으니 허전해서 문 양쪽에 횟불(?) 도 달아주었다.

Portal 오브젝트를 만들고 Collider와 Rigidbody를 붙여서 플레이어가 문에 닿았을 경우에 처리할 수 있게 했고 문이 활성화 된 것처럼 보이도록 포탈 이펙트를 자식으로 추가했다. 

Portal 스크립트를 생성하여 Portal 오브젝트에 추가했다. OnTriggerEnter 함수에서 충돌한 오브젝트의 Tag가 Player일 경우에 OnPlayerEnter 델리게이트를 실행시키도록 했다. OnPlayerEnter는 GameManager에서 연결해주었다.

몬스터가 아직 남아 있을 경우 포탈을 비활성화시킬 수 있도록 InActive 프로퍼티를 만들어 외부에서 활성화 및 비활성화 할 수 있도록 구현했다. 

public class Portal : MonoBehaviour {
   public Action OnPlayerEnter; //플레이어가 포탈과 충돌했을 때 실행되는 델리게이트
   
   [SerializeField] private ParticleSystem portalEffect;
   private Collider collider;
   
   private bool isActive = false;
   public bool IsActive {
      get => isActive;
      set {
         isActive = value;
      
         if (isActive) {
            portalEffect.Play();
            collider.enabled = true; // 플레이어와 충돌시 감지할 수 있게 Collider의 enable을 true로 바꿈
         } else {
            portalEffect.Stop();
            collider.enabled = false; // 플레이어와 충돌해도 감지하지 않도록 Collider의 enable을 false로 바꿈
         }
      }
   }

   private void Awake() {
      collider = GetComponent<Collider>();
   }

   private void OnTriggerEnter(Collider other) {
      // 충돌한 오브젝트의 Tag가 Player인지 체크
      if (!other.CompareTag("Player")) {
         return;
      }

      collider.enabled = false;
      OnPlayerEnter?.Invoke();
   }
}

 

GameManager

플레이어가 포탈에 들어가면 Portal의 OnPlayerEnter 델리게이트가 실행되면서 GameManger와 연결되어 있던 OnPlayerEnterPortal 함수가 실행된다. 

플레이어가 포탈에 들어가면 플레이어 조작을 비활성화시키고 로딩 화면을 보여준다. 로딩 화면이 보여지는 동안에는 플레이어 위치를 리셋시키고 게임이 다시 시작될 수 있도록 게임을 리셋시킨다. 이후 다시 로딩 화면을 꺼준다.

private void Awake() {
    portal = GameObject.Find("Portal").GetComponent<Portal>();
    ...
}

private void Start() {
    ...
    portal.OnPlayerEnter = UniTask.Action(async () => await OnPlayerEnterPortal());
    ...
}

private async UniTask OnPlayerEnterPortal() {
    InputManager.Instance.IsAvailable = false;
    InputManager.Instance.Reset();
    UIManager.Instance.ShowLoadingView();

    await UniTask.Delay(1000);
     
    ResetPlayer();
    ResetGame();
    
    await UniTask.Delay(1000);

    InputManager.Instance.IsAvailable = true;
    UIManager.Instance.HideLoadingView();
}

//플레이어 상태를 리셋시키고 위치를 초기 위치로 옮긴다.
private void ResetPlayer() {
    playerController.ResetBehaviour();
    playerController.transform.position = spawnPoint;
}

//몬스터 오브젝트를 모두 Destroy하고 포탈을 비활성화한 후 게임을 다시 시작한다.
public void ResetGame() {
    enemySpawnController.RemoveAllEnemies();

    portal.IsActive = false;
    StartGame().Forget();
}

 

LoadingView

로딩은 간단하게 구현했다. Canvas를 생성하고 Image와 Text를 자식으로 생성하여 아래처럼 만들었다. Canvas 오브젝트에는 CanvasGroup 컴포넌트를 추가했다.

 

LoadingView 스크립트를 생성하여 아래와 같이 작성했다. 로딩 화면을 보여줄 때 서서히 나타나고 사라지도록 코루틴을 이용하여 CanvasGroup의 Alpha에 값을 더해주거나 빼주는 식으로 구현했다. 

public class LoadingView : MonoBehaviour {
    [SerializeField] private float speed = 1f;

    private CanvasGroup canvasGroup;

    private void Awake() {
        canvasGroup = GetComponent<CanvasGroup>();
    }

    public void FadeIn() {
        StartCoroutine(FadeInCoroutine());
    }

    private IEnumerator FadeInCoroutine() {
        while (canvasGroup.alpha < 1) {
            canvasGroup.alpha += Time.deltaTime * speed;
            yield return null;
        }
    }

    public void FadeOut() {
        StartCoroutine(FadeOutCoroutine());
    }
    
    private IEnumerator FadeOutCoroutine() {
        while (canvasGroup.alpha > 0) {
            canvasGroup.alpha -= Time.deltaTime * speed;
            yield return null;
        }
        
        gameObject.SetActive(false);
    }
}


실행 결과

 


 

이제 플레이어가 현재 몇층에 있는지 확인할 수 있게 층을 표시해주고 특정 층에서는 보스 몬스터가 등장할 수 있도록 보스 몬스터도 구현해야겠다. 그리고 몬스터를 잡고 얻은 재화를 사용하여 더 강해질 수 있는 기능들을 개발하면 될 것 같다. 아직 많이 남았지만 지금처럼 조금씩 하다보면 올해에는 완성하겠지 ..

 

 

사용 에셋

Character

POLYGON Modular Fantasy Hero Characters (Synty Studios)

POLYGON Fantasy Rivals (Synty Studios)

 

Animation

Oriental Sword AnimSet (wemakethegame)

DOTween (Demigiant)

 

VFX

Magic Arsenal (Magic Arsenal)

 

UI

GUI PRO Kit - Fantasy RPG (Layer Lab)

 

ETC

UniTask (neuecc - Yoshifumi Kawai)