[ 애니메이션 적용 ]
트러블 슈팅
애니메이션을 적용했을 때 스프라이트가 바뀌면서 캐릭터가 깜빡거리는 현상이 발생했다.
또한 CameraController가 오브젝트의 위치를 참조하지 못하면서 카메라 화면도 이동하지 않게 됐다.
캐릭터 오브젝트를 할당하지 않았던 간단한 문제였다. 이후 정상적으로 깜빡임 현상 없이 카메라 화면도 잘 움직였다. 너무 기본적인 거라 당연히 했을 거라고 생각하고 까먹을 때가 있는데, 뭔가 잘 안 된다면 일단 컴포넌트에 오브젝트를 할당했는지 체크해 보자.
[ 이름 입력 ]
StartScene을 생성해서 이름을 입력하고 Join 버튼을 누르면 MainScene으로 이동한다. 단, 이름은 2~10글자여야 한다.
트러블 슈팅
public class JoinButton : MonoBehaviour
{
public Text text;
public void StartGame()
{
if (text.text.Length >=2 && text.text.Length <= 10)
{
SceneManager.LoadScene("MainScene");
}
}
}
JoinButton 스크립트를 생성해서 입력받은 텍스트가 2글자 이상, 10글자 이하라면 메인 씬으로 넘어가고, 이외는 아무것도 동작되지 않게 했다. 하지만 몇 글자를 입력하든 무조건 메인 씬으로 로드되는 현상이 발생했다.
public void StartGame()
{
Debug.Log("입력 길이: " + text.text.Length);
if (text.text.Length >=2 && text.text.Length <= 10)
{
SceneManager.LoadScene("MainScene");
}
else
{
Debug.Log("입력한 글자수가 2~10글자 사이여야 합니다.");
}
}
현재 어떻게 작동되고 있는지 파악하기 위해서 디버그 로그를 추가했다. 1글자는 메인 씬으로 넘어가지 않고 안내문이 출력됐다. 2~9글자는 정상적으로 입력 길이가 출력됐고 메인 씬으로 넘어갔다. 하지만 10글자 이상부터는 입력 길이가 9로 출력되며 메인 씬으로 넘어갔다.
public InputField inputName;
public void StartGame()
{
Debug.Log("입력 길이: " + inputName.text.Length);
if (inputName.text.Length >= 2 && inputName.text.Length <= 10)
{
GameManager.Instance.InputName(inputName.text);
SceneManager.LoadScene("MainScene");
}
else
{
Debug.Log("입력한 글자수가 2~10글자 사이여야 합니다.");
}
}
텍스트 오브젝트를 컴포넌트에서 할당하지 않고, 싱글톤 인스턴스를 설정해서 입력된 이름을 받아오는 메서드를 사용했다. InputField 컴포넌트는 텍스트 입력을 받아오는 UI 컴포넌트이기 때문에, Text 컴포넌트보다 안정적으로 입력 데이터를 받아올 수 있다. Text 컴포넌트는 입력을 받는 것보다는 문자를 표시하는 용도로 사용된다.
싱글톤에 대한 내용은 아래에서 자세히 확인할 수 있다.
[ 씬 전환 시 데이터 유지 ]
트러블 슈팅
StartScene에서 이름 입력을 받는 텍스트 컴포넌트를 MainScene에서 사용하려고 했는데, 서로 다른 씬끼리는 오브젝트를 참조할 수 없었다.
그래서 GameManager에서 싱글톤 인스턴스를 설정하고, 씬이 변경될 때 이름을 입력받은 텍스트 오브젝트가 파괴되지 않는 코드를 작성했다.
public class GameManager : MonoBehaviour
{
public static GameManager Instance;
public string inputName;
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
public void InputName(string name)
{
inputName = name;
}
public string GetName()
{
return inputName;
}
}
Awake 메서드에서 싱글톤 인스턴스가 아직 초기화되지 않았다면, 현재 객체를 싱글톤 인스턴스로 설정하고 씬이 전환되었을 때에도 오브젝트가 파괴되지 않게 한다. 원래는 씬이 변경될 때 현재 씬에 있는 모든 게임 오브젝트가 파괴되지만, DontDestroyOnLoad를 사용하면, 새로운 씬이 로드됐을 때 오브젝트가 파괴되지 않고 변경된 씬에서도 유지된다. 만약 싱글톤 인스턴스가 존재한다면 중복 인스턴스를 파괴해서 싱글톤이 단 하나만 존재하도록 한다.
해당 스크립트는 StartScene의 텍스트 오브젝트의 컴포넌트로 추가하고, 이름 입력 값을 inputName에 할당한다.
public class CharacterName : MonoBehaviour
{
public Text inputName;
private void Start()
{
inputName.text = GameManager.Instance.GetName();
}
}
MainScene에서 이름 입력 값을 받아올 오브젝트에 해당 스크립트를 컴포넌트에 추가한다. 그리고 inputName에 이름이 표시될 텍스트 오브젝트를 할당한다. 그러면 싱글톤을 통해 StartScene에서 입력된 이름값을 받아와서 MainScene의 오브젝트에서 사용할 수 있다.
추가로 코드가 모두 알맞게 작성되었는데도 정상적으로 실행이 되지 않는 상황이 발생했다. 그 이유는 변경된 스크립트를 하나하나 저장하지 않았기 때문이었다. 비주얼 스튜디오에서 저장 버튼을 누르면 해당 cs 파일만 저장되고, 다른 파일들은 저장되지 않기 때문에 변경 사항이 있는 파일은 모두 개별적으로 저장을 해줘야 한다. 그래야 유니티에서도 정상적으로 반영되어 원했던 동작을 실행하게 할 수 있다.
[ 회고 ]
애니메이션을 적용할 때, 깜빡거리는 현상은 구글링을 해도 나오지 않아서 답답했다. 해당 기능을 새벽에 구현했는데, 밤샘할 때는 피곤해서 아무리 찾아봐도 문제를 찾을 수가 없었다. 하지만 조금 자고 일어나서 다시 보니 그냥 컴포넌트에 오브젝트를 할당하지 않았던 아주 간단한 문제였다. 역시 피곤하면 능률이 떨어지니까 오히려 급할수록 수면 시간을 어떻게든 확보해서 체력을 보충해야겠다는 생각이 들었다.
그리고 Text 컴포넌트가 문자와 관련된 거라면 모두 처리를 하는 줄 알았는데, 입력 값을 받아오는 데는 적합하지 않다는 것을 알게 되었다. 10글자 이상의 문자를 모두 9글자로 처리하는 버그를 고치려고 애썼는데, 싱글톤을 생성하고 InputField를 사용하고 나니 깔끔하게 해결이 돼서 컴포넌트의 기능을 잘 알고 있는 것도 중요하다는 것을 알게 되었다.
또한 싱글톤을 이용하면 씬 전환 시 사라지는 데이터도 싱글톤 인스턴스를 통해 전달할 수 있다는 것을 배웠다. 싱글톤은 단순히 단 하나만 존재해야 하는 데이터들만 저장하는 역할을 하는 줄 알았는데, 씬 간 데이터를 전달할 때에도 사용될 수 있다는 것과 하나의 기능에서 다양한 동작을 수행할 수 있음을 깨달았다.
'Coding > Unity' 카테고리의 다른 글
[내일배움캠프 30일차 TIL] 인벤토리 창 트러블 슈팅 (0) | 2024.05.28 |
---|---|
[내일배움캠프 23일차 TIL] 스크립터블 오브젝트, 레이어 마스크, 비트 시프트 연산, 오브젝트 풀링, FindGameobjectWithTag (0) | 2024.05.17 |
[내일배움캠프 20일차 TIL] 카메라 추적, 보간 적용 (0) | 2024.05.13 |
[내일배움캠프 19일차 TIL] New Input System, 이벤트 처리 (0) | 2024.05.10 |
[내일배움캠프 18일차 TIL] 쿼터니언, 아크탄젠트 (0) | 2024.05.09 |