instance를 부여하는 싱글톤 스크립트가 부여된 오브젝트는 DontDestroyOnLoad를 이용해서 새로운 scene에서 사라지지 않고 이전 scene에서 갖고 있던 다양한 변수들을 유지한다. ( UnityEngine.SceneManagement 선언필요 )
이를 활용해서 소리를 끊기지않고 유지하거나, 값을 소실없이 활용하는 방법이 있다.
그렇다면 public GameObject를 선언하고 연결고 Scene을 바꾸면 어떻게 될까?
오류가 난다.
싱글톤 오브젝트는 DontDestroyOnLoad 로 파괴되지 않지만 연결시킨 GameObject는 그렇지 않다.
변수처럼 싱글톤에 GameObject를 선언해서 연결시킨다면 다른 scene으로 이동하여도 쓸 수 있다고 생각했지만 그러지 못했다.
어떻게 해서든 유지하고 싶다면 해당 GameObject에도 DontDestroyOnLoad를 붙이면 가능하겠지만, 좋은 방법은 아니다.
싱글톤 오브젝트에 변수만을 저장하고 해당하는 값에 따라서 해당 scene의 오브젝트에서 상호작용하는 것이 좋다.
처음에 이미지 넣는 것을 배울때는 GameObject를 생성하고 그 위에 이미지를 드래그 앤 드랍으로 넣었다.
그러다 보면 이미지에 따라서 너무 크거나 너무 작아지는 현상이 있는데 이미지를 재활용하지 않을 경우 단순히 scale 값을 조정하여서 사용하였다.
하지만, 같은 Prefab에서 다른 이미지를 넣는 경우 사이즈가 다르면 생각한 것과는 다른 결과가 나타날 수 있다.
처음에는 이러한 문제를 사진마다 가지고 있는 Pixel Per Unit을 변경하여 적용되는 상태를 미리 확인하고 조절하였다. 하지만 이미지가 많아지거나 다른 GameObject에 사용된다면 문제가 또 발생한다.
그래서 이를 방지하기 위해서는 Image UI를 생성하여서 직접 Image의 Source Image에 넣어주는 것이 좋다.
Image의 Source Image에 직접 넣어주면 가로 세로의 비율이 많이 다른 사진도 자신이 지정한 image범위 내에 어떻게든 넣어주기 때문이다.
( 사진이 좀 이상해질 수 있기 때문에 비율이 너무 다른 사진은 편집을 해주자. )
또한 코드적으로도 불필요하게 Sprite renderer를 사용(&선언)할 필요 없이 오브젝트의 image component에 바로 접근하여서 변경해 줄 수 있다.
또한, GameObject라고 뭉뚱그려서 코드를 작성하면 나중에 다른 사람이 볼 때 가독성도 떨어질 수 있다.
구현이라고 생각하면 GameObject와 Script가 상호작용하여서 값이 변경되거나 다른 오브젝트가 생성이나 소명을 해야한다고 생각했다.
처음 버튼 잠금장치의 UI를 만들려고 할 때도 그러했다. Image값을 라운드 클리어 값에 따라서 바꿔주려고 했었다. 하지만 오류가 계속 발생했고 팀원들에게 어떻게 해야할지 물으니 한 팀원이 애니메이션 기능을 활용하면 되는 것이 아니냐고 했다. 그 한마디에 순간 깨달았다. 결국 애니메이션도 하나의 스크립트인 것이다. 이미지가 달라지는 애니메이션만 만들고 그것을 원하는 타이밍에 호출한다면, 내가 원하는 수행을 더 적은 참조, 상호작용으로 마무리 할 수 있는 것이다. 사실상 애니메이션도 스크립트이며 이것을 잘 활용하는 것은 매우 중요하다.
Awake가 Start보다 빠르게 호출된다고만 듣고 코드를 짜고있는데,
참조 선언을 한번만 하면 되는 오브젝트가 있었다. 해당 참조를 많이 사용하다보니 Update에는 넣고 싶지 않았고, Start 부분에 넣어주었다. 그랬더니 언제나처럼 오류가 발생했다. 그래서 계속 Update 부분에만 넣다가 다른 사람의 코드를 보니 Awake에 한번 만 선언한 것이 보였다.
그래서 검색해 보니 Awake는 오브젝트가 만들어지기도 전인 인스턴스화 될 때 같이 호출되는 명령어이고, Start는 오브젝트가 실제로 다 만들어지고 난 이후에 호출되는 것이다. ( Start는 모든 Awake가 실행한 이후에 실행, 오브젝트가 활성화 되어있지 않아도 오류가 발생한다. )
Awake는 문서만으로도 선언이 가능하지만 Start는 실제가 있어야만 하는 것이다. 그러다보니 Start가 값을 받기도 전에 Update에서 해당값을 사용하려고하면 오류가 발생하는 것이다.
( 우리가 게임에 접속했을 때, 우리의 화면에는 로딩창이 떠도 다른 사용자들 눈에는 접속이 되었다고 뜨는 것과 비슷한? )