4주차 개인프로젝트 트러블 슈팅 목록
플레이어가 움직이지 않던 문제
- 문제&에러에 대한 정의
Player의 조작을 위해 Input Action을 사용하였으나 플레이어가 움직이지 않았음.
- 내가 한 시도
- 일단 로그를 찍어서, OnMove()가 호출되는지 확인하였음
- 내부 변수인 MovementDirection을 수정만 하지 대입을 안하는 상태였음.
- 해결 방법
Movement 함수 작성함
- 이 문제&에러를 다시 만나게 되었다면?
Vector3은 Struct라, transform.position을 수정한다고 바로 변경되지 않고 대입해야 한다는 점을 잊지 않기.
사용하려는 값의 타입을 제대로 확인하자.
플레이어 스프라이트가 뒤집어지던 문제
- 문제&에러에 대한 정의
플레이어가 움직이다보면 아래 사진처럼 이상하게 뒤집어짐
- 해결 방법
Rotate Z 를 Freeze 해보았는데 성공했음.
- 새롭게 알게 된 점
콜라이더에 부딛치다보면 회전할 수 있으니 주의.
- 이 문제&에러를 다시 만나게 되었다면?
콜라이더의 설정에 유의하자.
NPC에 레이캐스트가 맞지 않던 문제
- 문제&에러에 대한 정의
상호작용 처리를 하려는데, 아무리 레이캐스트를 쏴도 NPC한테 맞지가 않았음
- 내가 한 시도
로그를 찍어봤는데, 충돌체가 Player로 찍혀있었음
- 해결 방법
레이어마스크 추가해서 NPC로 인식하게 함. 플레이어가 레이를 쏘는데 문제는 플레이어도 콜라이더를 가지고 있어서 그랬던 것 같음.
- 이 문제&에러를 다시 만나게 되었다면?
레이어마스크를 활용하자.
UI의 Sorting Layer가 변경되지 않던 문제
- 문제&에러에 대한 정의
말풍선 부분이 저렇게 foreground에 짤려서 보임
- 내가 한 시도
Renderer 에서 Sorting Layer를 변경해 보았음. 그리고 Order in Layer도 변경해봄
- 해결 방법
생각해보니 NPC들을 BaseNPC로 프리팹 화 해서 가지고 있었지만 이걸 가져온 뒤에는 Unpacking 했기 때문에 각각의 NPC에 Sorting Layer가 변경되지 않았음.
- 새롭게 알게 된 점
프리팹을 Unpacking 하면 연동이 끊긴다.
- 이 문제&에러를 다시 만나게 되었다면?
프리팹화 되어있는거 다시 한 번 확인하기
미니게임 재시작 시 바로 GameUI로 변경되지 않던 문제
- 문제&에러에 대한 정의
재시작을 하면 HomeUI가 아니고 바로 GameUI 되면서 게임 시작할 수 있도록 하려고 했는데 잘 되지 않았음.
- 내가 한 시도
GameManager instance로 해주고 디버그 켜서 제대로 활성화되나 해주고 계속 봤음
- 해결 방법
isFirstLoading 이 static이 아니었음
- 새롭게 알게 된 점
static은 Scene 재로드해도 남아있음.
- 이 문제&에러를 다시 만나게 되었다면?
내가 원하는 변수가 static인지 다시 한 번 확인해라
일시정지 이후 아무런 키 입력이 작동하지 않던 문제
- 문제&에러에 대한 정의
Player에 Pause 키 입력을 구현하고,
Pause를 누르면 일시정지 되도록 한뒤에 다시 눌렀을 경우에는 일시정지가 풀리도록 작업했음
Pause를 눌렀을 때 플레이어를 SetActive(false)를 해서 숨기게 했음
근데 그러다보니 Player Input 자체도 SetActive(false)가 되어서 돌아가지지가 않았음
- 내가 한 시도
그러면 일시정지는 게임매니저가 가지고 있게 하자! 는 아이디어로 부딛혀봄
- 해결 방법
일시정지를 게임 매니저가 가지고 있게 했더니 성공함
- 새롭게 알게 된 점
SetActive(false)를 해버리면 그 안에 있는 스크립트도 전부 작동을 멈추니 주의할 것.
- 이 문제&에러를 다시 만나게 되었다면?
캐릭터 조작 외의 다른 유틸적인 부분들은 조작을 따로 빼자
JSON 직렬/역직렬화가 안됐던 문제
- 문제&에러에 대한 정의
C#에서 했던것처럼 직렬화/역직렬화를 위해 퍼블릭 프로퍼티로 설정했었음
- 내가 한 시도
Serializable도 넣고 SerializeField도 넣고 해봤음. 근데 안됐음.
- 해결 방법
그러다 마지막에 혹시 JsonUtiilty의 직렬화 정책이 프로퍼티 기준이 아니고 일반 변수 기준인가 싶었음 그래서 일반 변수로 만들었더니 됐음
- 새롭게 알게 된 점
JsonUtility는 프로퍼티 아니고 변수를 기준으로 함
해결(이해)하지 못한 문제들
부모 클래스의 함수를 부를 때 자식 클래스의 변수가 사용되지 않았던 문제
- 문제&에러에 대한 정의
Global.GameManager 안에는 이런 코드가 있었다.
protected string bestScoreKey;
...
public virtual void GameOver()
{
Debug.Log("Game Over!");
int bestScore = PlayerPrefs.GetInt(bestScoreKey, 0);
if (currentScore > bestScore)
{
bestScore = currentScore;
PlayerPrefs.SetInt(bestScoreKey, bestScore);
}
Debug.Log($"key : {bestScoreKey} | score : {bestScore}");
}
Global.GameManager를 상속받는 다른 미니게임들의 GameManager는 이렇게 구성했다.
private void Awake()
{
instance = this;
bestScoreKey = "FlappyBestScore";
uiManager = FindObjectOfType<UIManager>();
}
...
public override void GameOver()
{
base.GameOver();
Debug.Log($"key : {bestScoreKey} | score : {bestScore}");
uiManager.SetGameOver(currentScore, bestScore);
}
목적은 Global.GameManager에 bestScoreKey를 미니게임.GameManager에서 각각 설정해 주고, GameOver시에는 base.GameOver()를 실행한 뒤에 각각 연결된 uiManager에 SetGameOver를 호출하려는 생각이었다.
분명 Global.GameManager의 디버그 로그에서는 제대로 bestScore가 불러와졌음에도 불구하고
그런데, 미니게임.GameManager의 디버그 로그를 보았을 때 bestScoreKey가 비어있었다.
- 내가 한 시도
- FlappyPlane.GameManager에서, 아래의 코드를 변수 부분에 추가 하였으나 실패하였다.
protected new string bestScoreKey = "FlappyBestScore";
- FlappyPlane.GameManager에서, void GameOver() 부분을 아래와 같이 변경하였으나 실패하였다.
public override void GameOver()
{
Debug.Log($"key : {bestScoreKey} | score : {bestScore}");
uiManager.SetGameOver(currentScore, base.bestScore);
}
- 결국, Global.GameManager의 GameOver를 abstract로 만들고, 각각의 미니게임.GameManager에서 아래의 코드로 변경하였다.
public override void GameOver()
{
Debug.Log("Game Over!");
int bestScore = PlayerPrefs.GetInt(bestScoreKey, 0);
if (currentScore > bestScore)
{
bestScore = currentScore;
PlayerPrefs.SetInt(bestScoreKey, bestScore);
}
Debug.Log($"key : {bestScoreKey} | score : {bestScore}");
uiManager.SetGameOver(currentScore, bestScore);
}
- 다만 이렇게 하면 코드가 중복됨…
충돌 처리가 되지 않았던 문제
- 문제&에러에 대한 정의
CodeShooter를 만드는 중에 생긴 일.
Bullet 은 BoxCollider2D와 RigidBody2D를 가지고 있었음.
Enemy는 BoxCollider2D만 가지고 있었음.
Bullet이 Enemy를 맞으면 Enemy의 Die를 호출하고 자기 자신을 파괴하도록 하였음.
OnCollisionEnter2D를 사용함.
근데, Debug.Log를 사용했는데도 애초에 충돌했다는 문구가 안뜸.
- 내가 한 시도
충돌 처리를 Bullet이 아니고 Enemy에서 하게 해봤음
- 해결 방법
성공함!
- 새롭게 알게 된 점
충돌 처리를 어디서 하느냐에 따라 좀 다른듯.. 근데 왜 안됐는지 모르겠음.
강의 코드 분석
--- config: class: hideEmptyMembersBox: true layout: dagre --- classDiagram direction TB class GameManager { } class AnimationHandler { } class BaseController { } class EnemyController { } class PlayerController { } class ResourceController { } class StatHandler { } class EnemyManager { } class ProjectileManager { } class SoundManager { } class SoundSource { } class UIManager { } class BaseUI { } class GameOverUI { } class GameUI { } class HomeUI { } class MeleeWeaponHandler { } class ProjectileController { } class RangeWeaponHandler { } class WeaponHandler { } class DustParticleControl { } BaseController <|-- EnemyController BaseController <|-- PlayerController EnemyManager o-- EnemyController WeaponHandler <|-- RangeWeaponHandler WeaponHandler <|-- MeleeWeaponHandler ResourceController -- AnimationHandler BaseController -- WeaponHandler BaseController -- StatHandler BaseUI <|-- GameOverUI BaseUI <|-- GameUI BaseUI <|-- HomeUI ResourceController -- BaseController ResourceController -- StatHandler SoundManager -- SoundSource ProjectileManager -- ProjectileController MeleeWeaponHandler -- ProjectileController GameManager -- PlayerController GameManager -- EnemyManager GameManager -- ResourceController UIManager -- GameOverUI UIManager -- GameUI UIManager -- HomeUI
-
TopDown 코드의 구조는 위와 같이 되어있음을 확인했음.
-
BaseController에서는 보는 방향으로 자동으로 움직이게 설정하고
-
PlayerController에서는 움직임을 입력 기준으로, EnemyController에서는 플레이어를 바라보는 방향을 가지도록 설정함