목차
멋쟁이사자처럼 로켓단 인턴쉽
25.08.13
회의록
>> 안건
- 업무 업데이트
- 질문 혹은 피드백 요청
- 주요 안건
- 1회차 완전플레이 마일스톤 및 작업카드 작성 및 분담
- 목표 개발 진행
- 향후 마일스톤
- 1회차 완전플레이
- 완전 완성
>> 회의 내용
- 프로토타입 개발 완료 확인.
- 1회차 완전플레이 개발을 위한 마일스톤 재정립
- 일감 작업카드 생성 및 분배 후 작업시작
- 익일 작업 분배건 내일까지 완성 목표
- 이후부터 일감을 유동적으로 생성 및 작업하여 마일스톤 도달을 위한 개발기간 단축을 도모.
새로 만들어진 UI Manager
: 어제 일과시간이 끝난 후에 팀장 분께서 UI Manager를 새로 만드셨고, 오늘 가져오셨다. 내가 만든 UI Manager가 초라할 정도로 구조가 잘 짜여져있었다.
--> 내가 만든 걸 부정 당한 것 같아서 많이 속상했지만 이건 공부가 아니라 일을 하는 인턴쉽이고, 정해진 시간 안에 게임을 만들어야 하는 입장에서 나의 속도와 실력으로는 해낼 수 없기에 받아들였다. 내가 더 잘하는 수 밖에 없다.
>> 코드
1. UIManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIManager : Singleton<UIManager>
{
[SerializeField] public TitleUIController titleUIController;
[SerializeField] public InGameUIController inGameUIController;
[SerializeField] public PopupUIController popupUIController;
[SerializeField] private PanelController panelController;
[SerializeField] private PopupController popupController;
protected override void Initialize()
{
base.Initialize();
// 초기화 로직 필요 시, 추가
}
public void SetTitleUIController(TitleUIController titleUIController)
{
this.titleUIController = titleUIController;
}
public void SetInGameUIController(InGameUIController inGameUIController)
{
this.inGameUIController = inGameUIController;
}
public void SetPopupUIController(PopupUIController popupUIController)
{
this.popupUIController = popupUIController;
}
public void ReleasePopupUIController()
{
popupUIController = null;
}
public void ShowBackgroundImage(bool isShow)
{
popupUIController.backgroundImage.gameObject.SetActive(isShow);
}
// Panel 관련
public void OpenPanel(GameObject panel) => panelController.OpenPanel(panel);
// Popup 관련
public void ShowPopup(GameObject popup) => popupController.ShowPopup(popup);
public void ClosePopup(GameObject popup) => popupController.ClosePopup(popup);
}
2. TitleUIController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Serialization;
public class TitleUIController : Singleton<TitleUIController>
{
[SerializeField] private RectTransform _titleUI;
//새로 추가한 TitleUI는 이곳 아래에 추가해주시고, 프리팹의 자식개체로 넣은 뒤 인스펙터에서 할당해주세요.
//이 싱글톤 객체를 통해 UI 접근을 용이하게 관리합니다.
//ex. public TimerUIController timerUIController;
public MainMenuUIController mainMenuUIController;
public SubMenuUIController subMenuUIController;
//여기까지
protected override void Initialize()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
{
SceneManager.sceneLoaded -= OnSceneLoaded;
UIManager.Instance.SetTitleUIController(this);
}
public void ShowTitleUI()
{
_titleUI.gameObject.SetActive(true);
}
public void HideTitleUI()
{
_titleUI.gameObject.SetActive(false);
}
#region MainMenuUI
public void ShowMainMenuUI()
{
mainMenuUIController.gameObject.SetActive(true);
}
public void HideMainMenuUI()
{
mainMenuUIController.gameObject.SetActive(false);
}
#endregion
#region SubMenuUI
public void ShowSubMenuUI()
{
subMenuUIController.gameObject.SetActive(true);
}
public void HideSubMenuUI()
{
subMenuUIController.gameObject.SetActive(false);
}
#endregion
}
3. InGameUIController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class InGameUIController : Singleton<InGameUIController>
{
[SerializeField] private RectTransform _inGameUI;
//새로 추가한 InGameUI는 이곳 아래에 추가해주시고, 프리팹의 자식개체로 넣은 뒤 인스펙터에서 할당해주세요.
//이 싱글톤 객체를 통해 UI 접근을 용이하게 관리합니다.
//ex. public TimerUIController timerUIController;
public TimeUIController timeUIController;
public InteractionUIController interactionUIController;
//여기까지
protected override void Initialize()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
{
SceneManager.sceneLoaded -= OnSceneLoaded;
UIManager.Instance.SetInGameUIController(this);
}
public void ShowInGameUI()
{
_inGameUI.gameObject.SetActive(true);
}
public void HideInGameUI()
{
_inGameUI.gameObject.SetActive(false);
}
#region TimeUI
public void ShowTimeUI()
{
timeUIController.gameObject.SetActive(true);
}
public void HideTimeUI()
{
timeUIController.gameObject.SetActive(false);
}
#endregion
#region InteractionUI
public void ShowInteractionUI()
{
interactionUIController.gameObject.SetActive(true);
}
public void HideInteractionUI()
{
interactionUIController.gameObject.SetActive(false);
}
#endregion
}
4. PopupUIController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class PopupUIController : Singleton<PopupUIController>
{
[SerializeField] public Image backgroundImage;
//새로 추가한 InGameUI는 이곳 아래에 추가해주시고, 프리팹의 자식개체로 넣은 뒤 인스펙터에서 할당해주세요.
//이 싱글톤 객체를 통해 UI 접근을 용이하게 관리합니다.
//ex. public PauseUIController pauseUIController;
public PauseUIController pauseUIController;
//여기까지
protected override void Initialize()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
{
SceneManager.sceneLoaded -= OnSceneLoaded;
UIManager.Instance.SetPopupUIController(this);
}
#region PauseUI
public void ShowPauseUI()
{
pauseUIController.ShowPopup();
}
public void HidePauseUI()
{
pauseUIController.ClosePopup();
}
#endregion
}
5. MainMenuUIController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class MainMenuUIController : MonoBehaviour
{
[SerializeField] private RectTransform _rectTransform;
[SerializeField] private CanvasGroup _canvasGroup;
[SerializeField] private Button _gameStartButton;
[SerializeField] private Button _gameTutorialButton;
private void Awake()
{
//버튼 클릭이벤트 등록
_gameStartButton.onClick.AddListener(OnClickGameStartButton);
_gameTutorialButton.onClick.AddListener(OnClickGameTutotialButton);
}
public void OnClickGameStartButton()
{
GameManager.Instance.GoToInGame();
}
public void OnClickGameTutotialButton()
{
Debug.Log("OnClickGameTutotialButton");
}
}
6. SubMenuUIController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SubMenuUIController : MonoBehaviour
{
[SerializeField] private RectTransform _rectTransform;
[SerializeField] private CanvasGroup _canvasGroup;
[SerializeField] private Button _gameSettingButton;
[SerializeField] private Button _leaderBoardButton;
private void Awake()
{
//버튼 클릭이벤트 등록
_gameSettingButton.onClick.AddListener(OnClickGameSettingButton);
_leaderBoardButton.onClick.AddListener(OnClickLeaderBoardButton);
}
public void OnClickGameSettingButton()
{
Debug.Log("OnClickGameSettingButton");
}
public void OnClickLeaderBoardButton()
{
Debug.Log("OnClickLeaderBoardButton");
}
}
7. PauseUIController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PauseUIController : PopupController
{
[SerializeField] private RectTransform _rectTransform;
[SerializeField] private CanvasGroup _canvasGroup;
[SerializeField] private Button _resumeButton;
[SerializeField] private Button _retryButton;
[SerializeField] private Button _quitButton;
[SerializeField] private Button _audioToggleButton;
[SerializeField] private Button _vibrateToggleButton;
void Awake()
{
_resumeButton.onClick.AddListener(OnClickResumeButton);
_retryButton.onClick.AddListener(OnClickRetryButton);
_quitButton.onClick.AddListener(OnClickQuitButton);
_audioToggleButton.onClick.AddListener(OnClickAudioToggleButton);
_vibrateToggleButton.onClick.AddListener(OnClickVibrateToggleButton);
}
public void ShowPopup()
{
base.ShowPopup(gameObject);
}
public void ClosePopup()
{
base.ClosePopup(gameObject);
}
public void OnClickResumeButton()
{
ClosePopup();
GameManager.Instance.ResumeGame();
}
public void OnClickRetryButton()
{
}
public void OnClickQuitButton()
{
ClosePopup();
GameManager.Instance.ResumeGame();
GameManager.Instance.inGameController.Dispose();
GameManager.Instance.inGameController.QuitGame();
}
public void OnClickAudioToggleButton()
{
}
public void OnClickVibrateToggleButton()
{
}
}
8. InteractionUIController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class InteractionUIController : MonoBehaviour
{
[SerializeField] private RectTransform _rectTransform;
[SerializeField] private CanvasGroup _canvasGroup;
[SerializeField] private Button _acceptButton;
[SerializeField] private Button _negativeButton;
[SerializeField] private Button _pauseButton;
private void Awake()
{
//버튼 클릭이벤트 등록
_acceptButton.onClick.AddListener(OnClickAcceptButton);
_negativeButton.onClick.AddListener(OnClickNegativeButton);
_pauseButton.onClick.AddListener(OnClickPauseButton);
}
public void OnClickAcceptButton()
{
}
public void OnClickNegativeButton()
{
}
public void OnClickPauseButton()
{
GameManager.Instance.PauseGame();
UIManager.Instance.popupUIController.ShowPauseUI();
}
}
9. TimeUIController.cs
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class TimeUIController : MonoBehaviour
{
public TMP_Text workTimeText;
public TMP_Text dayText;
}
Audio Manager 제작
: 아주 간단한 기능만 존재하는 프로토타입은 얼추 만들어졌고, 이제 어느정도 1차 플레이는 가능할 정도의 게임을 만들기 위해 새로운 일감이 생겼다.
--> 그 중 나는 Audio Manager를 만드는 일감을 받았다.
▶ 팀장 분께서 새로 만드신 UI Manager의 구조처럼 짜기를 원하셨다.
--> 뭔가 비슷하게 짜긴 했는데, 아직 내가 이 구조를 정확히 이해하지 못한 것 같다.
>> 만드려고 하는 Manager 구조
- 어디서든 AudioManager를 Instance로 호출해서 BGM 또는 SFX를 재생할 수 있도록
- Audio Toggle을 눌렀을 때 BGM과 SFX 모두 꺼지도록
- AudioManager는 각 Controller를 조율만 하고, 재생이나 정지 등의 세부 로직은 각 Controller들이 담당하도록
- 새로운 BGM와 SFX를 추가할 때 간단히 추가할 수 있도록 --> 추가할 Audio를 Inspector에서 바인딩, Controller에서 재생 함수 추가, 사용할 곳에서 AudioManager를 호출하여 바로 사용
>> 작성 중인 코드
1. AudioManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AudioManager : Singleton<AudioManager>
{
[SerializeField] private BGMController bgmController;
[SerializeField] private SFXController sfxController;
public BGMController BGM => bgmController;
public SFXController SFX => sfxController;
private bool _isAudioOn = true;
protected override void Initialize()
{
base.Initialize();
_isAudioOn = true; // 기본값은 켜짐으로 설정
// 필요 시, 초기화 ex) 저장된 설정 로드
}
public void SetBGMController(BGMController bgmController)
{
this.bgmController = bgmController;
}
public void SetSFXController(SFXController sfxController)
{
this.sfxController = sfxController;
}
// Audio 토글을 통해 BGM 및 SFX On/Off
public void ToggleAudio()
{
_isAudioOn = !_isAudioOn;
bgmController.SetBGMOn(_isAudioOn);
sfxController.SetSFXOn(_isAudioOn);
}
}
2. BGMController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class BGMController : Singleton<BGMController>
{
[SerializeField] private AudioSource bgmSource;
// BGM을 추가하실 때, 여기에 추가해주세요.
[SerializeField] private AudioClip titleBGM;
[SerializeField] private AudioClip gameBGM;
// 여기까지
private AudioClip _currentBGM; // 현재 재생해야 할 BGM 저장
private bool _isBGMOn = true; // BGM이 켜져있는지 여부
public bool IsBGMOn() => _isBGMOn;
protected override void Initialize()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
{
SceneManager.sceneLoaded -= OnSceneLoaded;
AudioManager.Instance.SetBGMController(this);
}
// BGM를 추가하신 뒤, 아래 함수 모음에 재생 함수를 작성해주세요.
#region PlayBGM 함수 모음
public void PlayTitleBGM() => PlayBGM(titleBGM);
public void PlayGameBGM() => PlayBGM(gameBGM);
#endregion
// BGM 재생 (반복 O)
private void PlayBGM(AudioClip clip)
{
if (!_isBGMOn || clip == null) return;
bgmSource.clip = clip;
bgmSource.loop = true;
bgmSource.Play();
}
// BGM 중지
private void StopBGM()
{
bgmSource.Stop();
}
// _isBGMOn값을 조정하고 그에 따라 BGM 재생 및 중지
public void SetBGMOn(bool isBGMOn)
{
_isBGMOn = isBGMOn;
if (!_isBGMOn)
StopBGM();
}
}
3. SFXController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SFXController : Singleton<SFXController>
{
[SerializeField] private AudioSource sfxSource;
// SFX를 추가하실 때 여기에 추가해주세요.
[SerializeField] private AudioClip buttonClick;
[SerializeField] private AudioClip stamp;
// 여기까지
private bool _isSFXOn = true; // SFX가 켜져있는지 여부
public bool IsSFXOn() => _isSFXOn;
protected override void Initialize()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
{
SceneManager.sceneLoaded -= OnSceneLoaded;
AudioManager.Instance.SetSFXController(this);
}
// SFX를 추가하신 뒤, 아래 함수 모음에 재생 함수를 작성해주세요.
#region PlaySFX 함수 모음
public void PlayButtonClick() => PlaySFX(buttonClick);
public void PlayStamp() => PlaySFX(stamp);
#endregion
// SFX 1번 재생
private void PlaySFX(AudioClip clip)
{
if (!_isSFXOn || clip == null) return;
sfxSource.PlayOneShot(clip);
}
// _isSFXOn 조정
public void SetSFXOn(bool isSFXOn)
{
_isSFXOn = isSFXOn;
}
}
'Development > Internship' 카테고리의 다른 글
[멋사 로켓단 인턴쉽] 7일차 - Audio Manager 완성 (0) | 2025.08.14 |
---|---|
[멋사 로켓단 인턴쉽] 5일차 - UI Manager (2) | 2025.08.12 |
[멋사 로켓단 인턴쉽] 4일차 - 일감 분배 및 작업 시작 (3) | 2025.08.11 |
[멋사 로켓단 인턴쉽] 3일차 - 게임 구조 설계 (1) | 2025.08.08 |
[멋사 로켓단 인턴쉽] 2일차 - 기획 (3) | 2025.08.07 |