개인과제 제출 완료
빨리 끝내고 싶어 작업 속도를 올리고 싶어서 유튜브에서 노동요를 찾아서 들어봤다. 확실히 마음이 급해진다. 그만큼 속도가 빨라지는진 모르겠지만 마음이 급해지는 장점..?은 있었다. 남용하면 익숙해질거같으니 가끔 급할때 또 들으려한다. 오늘은 개인과제 제출하고, 저녁이후에는 기획데이터테이블에 대해 특강을 들었다. 엑셀로 데이터 저장하고 불러오고하는거 예전에 시도했다가 대차게 실패했던건데 기회가 되면 꼭 해보고 싶다. 아무튼 오늘의 TIL은 크게 쓸게 없으니 오늘 있던 트러블 슈팅? 조금 적어볼까한다
배경
프로젝트 전반에 걸쳐 PlayerAutoBinder 싱글톤을 이용해 PlayerStat을 바인딩하고, Stamina 스크립트에서 이를 구독하도록 구성하였다.
발단
게임을 실행해 보니 Stamina.BindAndSubscribe()에서 NullReferenceException이 발생하며 게임을 시작할 때 오류가 발생해 게임이 진행되지 않았다.
전개
에러 메시지를 추적해 보니 PlayerAutoBinder.Instance 또는 PlayerAutoBinder.Instance.PlayerStat이 null이었다.
코드 상으로는 둘 다 씬에 배치해뒀고 Awake()에서 바인딩하도록 했기 때문에 원인을 쉽게 파악할 수 없었다.
위기
코드엔 문제가 없어보였고 어디를 어떻게 수정해야 할지 알 수 없었다. 심지어 원래는 되다가 갑자기 안되기 시작한거라 더 종잡을 수가 없었다.
절정
Stamina스크립트가 PlayerAutoBinder이 PlayerStat을 가져오기 전에 참조하려했기 때문에 Null 오류가 뜬 것이라 유추하고, 그렇다면 스크립트 실행 순서에 문제가 있지 않을까 생각했다. 그래서 프로젝트 세팅 → Script Execution Order에서 PlayerAutoBinder를 Stamina보다 우선 실행되도록 순서를 조정하니 오류가 사라지고 정상적으로 동작되었다.
결말
아마Awake()와 OnEnable() 호출 순서에 문제가 있었던 것 같다. 결론적으로 스크립트 실행 순서를 조정하는 기능을 사용해서 문제를 해결할 수 있었다.
Time.timeScale & Input.anyKey 검사 문제배경
게임 시작 시 튜토리얼 화면을 띄우고 아무 키나 누르면 게임이 재개되도록 하기 위해 게임이 시작되면 Time.timeScale = 0되도록 했다.
발단
Start() 메서드 안에서 if (Input.anyKey)로 검사했더니, 키를 눌러도 튜토리얼이 사라지지 않고 시간이 멈춘 채 멈춰 있었다. 그리고 카메라가 마우스를 따라 회전이 가능했다.
전개
생각해보니Start()는 씬 로드 직후 딱 한 번만 호출되어
그 한 프레임에 키를 누르지 않으면 이후로는 입력이 절대 체크되지 않는다는 것을 떠올렸다.
절정
Start()문에 있는Time.timeScale = 0을 지우고,Update()문에서 if (Input.anyKeyDown)로 매 프레임 입력을 검사하도록 수정했다. 그리고 Look()이 있는 스크립트로 가서
if(Time.timeScale > 0.5f)
{
Look();
}
아무키 입력을 받으면 timeScale = 1f이 되니 그때 움직일 수 있도록 수정해주었다.
결말
이제 씬 시작 시 튜토리얼 화면이 보이고 사용자의 움직임을 막는 상태로 시작할 수 있게 되었다. 사용자가 아무 키나 누르면 즉시 Time.timeScale = 1로 돌아와 정상 플레이가 가능하게끔 해결되었다.
배경
SlotManager와 Stamina Canvas에 묶어 DontDestroyOnLoad로 유지했다. 다음 씬에서도 아이템 정보를 유지하기 위함이었다.
발단
Start 씬에서 소모된 스태미나 값이 Game 씬으로 넘어가도 그대로 고정되어, 이후 스태미나 UI가 Game 씬에 있는 플레이어가 아닌 Start씬에 있는 플레이어 기준 값으로 고정되어 변화량이 반영되지 않는 문제가 발생했다.
전개
Stamina.OnEnable()이 씬 로드 후 재호출되지 않아 새 씬에 있는 Player의PlayerStat에 구독을 걸지 못했던 것이다.
위기
절정
Stamina 스크립트에 SceneManager.sceneLoaded 콜백을 추가해, 씬이 로드될 때마다PlayerAutoBinder.Instance.PlayerStat를 재구독하도록 수정하였다.
결말
이제 Stamina UI가 매 씬마다 새 PlayerStat을 참조해 정상 동작하게 되었고 불필요한 sceneLoaded 코드도 꼭 필요한 일부 스크립트에서만 동작하게 하여 역할 분리와 코드 정리도 할 수 있었다.
디테일한 거 이거저거 구현해놓고 싶었는데 시간이 부족해서 어쩔 수 없이 제출하게 되었다. 그래도 필수구현은 했으니까 괜찮다. 그나저나 시연영상 찍는거 사이트 다시 알아봐야겠다. 용량이 전체적으로 맨날 크게 나와서 불편하다..