-
내일배움캠프 24일차 TIL - 유니티 입문 팀 프로젝트 3TIL/Unity 2024. 5. 20. 20:19
[학습요약]
유니티 입문 주차 팀 프로젝트를 진행하고 추가 요구사항 일부를 구현했다.
[학습내용]
어제에 이어서 버섯 피하기 게임 구현을 진행했다. 팀원들이 HP 시스템과 점수 시스템, 버섯 종류 다양화와 스킬 구현을 진행하는 동안 나는 사운드와 아이템 시스템을 구현했다.
배경음악(BGM) 추가
우선 구현할 사운드에는 버섯 충돌 시 출력될 효과음과, 게임 전반적으로 출력될 배경음악 등이 있다. 여기서 더 구현한다면 버튼 클릭음 정도가 될 것이다. 효과음은 구현 우선 순위를 낮게 잡았기 때문에, 우선 배경음악을 먼저 구현하고 후에 경과에 따라 효과음까지 구현하기로 했다.
먼저 오디오 매니저를 만들었다.
오디오 소스 컴포넌트를 집어넣고, 스크립트를 통해 이 곳에 유동적으로 클립을 재생시키는 구조로 구현했다. 배경음악으로 재생할 오디오 클립은 티모송을 넣어줬다.
using UnityEngine; public class AudioManager : MonoBehaviour { public static AudioManager Instance; public AudioSource audioSource; public AudioClip audioClip; private void Awake() { if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); } else Destroy(gameObject); } private void Start() { audioSource = GetComponent<AudioSource>(); audioSource.clip = audioClip; audioSource.Play(); } }
AudioManager.cs
게임 전반에 같은 음악을 재생할 것이기 때문에, DontDestroyOnLoad()를 이용하여 씬이 전환되더라도 파괴되지 않고 재생을 계속 유지할 수 있게 해주었다.
! 음원 파일이 제대로 임포트 되지 않는 현상 발생
오디오 클립으로 만들기 위해 .mp3 파일을 유니티 에셋폴더로 드래그해오자,
Errors during import of AudioClip ~~:
FSBTool ERROR: The format of the source is invalid, see output for Details.라는 에러가 발생했다.
시도
순간 오류인가 싶어서 다시 임포트 해 보거나, 유니티를 종료했다가 재시작해도 해결되지 않았다. 구글에 해당 오류를 검색해보자 여러 이유가 나왔는데, 파일 확장자 때문이 큰 거 같았다.
해결
어느 글에서 mp3 말고 ogg 확장자로 파일을 변환해서 임포트 해보라는 글을 찾았다. 그래서 ogg 파일로 임포트 하였더니 오류가 뜨지 않고 성공적으로 임포트 되었다.
아이템 시스템 추가
다음으로는 아이템 시스템을 구현했다. 우선 어떤 기능을 가지는 아이템을 구현할지 정리해보았다.
- HP 회복 아이템
- 일정 시간 무적 아이템
- 이동 속도 증가 아이템
- 사망 보험 아이템
우선 추상 클래스로 아이템 클래스를 만들고 그걸 자식 클래스에서 상속하여 아이템의 세부 기능을 구현하는 식으로 진행하기로 했다.
using System; using UnityEngine; public abstract class Item : MonoBehaviour { private void Start() { // 아이템 효과를 이벤트에 추가 ItemManager.Instance.ItemEvent += ItemEffect; // 초기 위치 설정 float x = UnityEngine.Random.Range(-4.7f, 4.7f); transform.position = new Vector3 (x, 5.5f, 0); } public void OnCollisionEnter2D(Collision2D collision) { // 땅에 접촉 시 파괴 if (collision.gameObject.CompareTag("Ground")) { ItemManager.Instance.DestroyedItem(); Destroy(gameObject); } // 플레이어와 접촉 시 아이템 효과를 발동시키고 파괴 if (collision.gameObject.CompareTag("Player") || collision.gameObject.CompareTag("Invincible")) { ItemManager.Instance.UseItem(collision.gameObject); Destroy(gameObject); } } // 아이템 효과를 자식 클래스에서 구현 public abstract void ItemEffect(GameObject player); }
Item.cs
using UnityEngine; public class HpItem : Item { private readonly int recoverAmount = 30; // 체력 회복량 public override void ItemEffect(GameObject player) { // HP 회복 RestoreHp(player); } public void RestoreHp(GameObject player) { // HealthSystem에서 주어진 HP 회복량만큼 회복 player.GetComponentInChildren<PlayerHealthSystem>().RecoverHp(recoverAmount); } }
HpItem.cs (Item 상속)
이런 식으로 HP 회복 아이템과 일정 시간 무적 아이템을 구현했다.
아이템은 GameManager를 통해 10초에 한 번씩 무작위 아이템을 버섯과 같이 화면 상단에서 떨어지도록 구현했다.
무적 아이템의 경우 5초간 버섯에 피격되지 않는데, 이 동안 몸이 황금색으로 바뀌어 시각적으로 알아볼 수 있도록 했다.
! Destroy() 때문에 코루틴이 제대로 동작하지 않는 현상 발생
캐릭터를 5초간 무적 상태로 만들기 위해 코루틴을 사용했다. 그런데 이 기능을 아이템에서 아이템에서 구현하려다 보니, 아이템이 사라질 때 코루틴도 같이 사라지는 현상이 발생했다.
시도
이벤트 형태로 만들어서 코루틴을 실행해보려고 했다. 그런데 StartCoroutine()이 아이템 클래스 안에 자리하고 있는 이상 근본적인 해결은 어려웠다.
해결
그래서 그냥 게임 매니저에게 5초 뒤 해야 할 후처리 기능을 던져주기로 했다. 게임 매니저 안에 메서드를 다시 구현하고, 그걸 이벤트로 받아서 실행하도록 구현했다.
학습
이왕 이렇게 된 거 코루틴에 대해서 배워보았다.
코루틴 기본 형태
IEnumerator MethodName(float f) { yield return new WaitForSefconds(f); // 내용 } ... float f = 0; StartCoroutine(MethodName(f)); // 호출 StartCoroutine("MethodName", f); // string으로 호출
yield return에는 여러 조건을 걸 수 있다.
- yield return null : 다음 프레임에 실행
- yield return new WaitForSeconds(float n) : n초 후에 실행
- yield return new WaitForSeeconsRealtime(float n) : n초 후에 실행(timeScale 영향 안 받음)
- yield break : 코루틴 종료
[결과물]
https://github.com/LolDaeNam/AvoidTeemoMushroom
[회고]
어제 예상한 거보다는 많이 구현한 거 같다. 그런데 역시 꾸미질 않으니 되게 없어보인다. 수요일에 꾸미기를 진행하겠지만, 조금 일찍 당겨볼까 생각 중이다.
'TIL > Unity' 카테고리의 다른 글
내일배움캠프 26일차 TIL - 유니티 입문 팀 프로젝트 5 (0) 2024.05.22 내일배움캠프 25일차 TIL - 유니티 입문 팀 프로젝트 4 (0) 2024.05.21 내일배움캠프 23일차 TIL - 유니티 입문 팀 프로젝트 2 (0) 2024.05.17 내일배움캠프 22일차 TIL - 유니티 입문 팀 프로젝트 (1) 2024.05.16 내일배움캠프 21일차 TIL - 스파르타타운 제작 마무리 (0) 2024.05.14