4주차 개인프로젝트 트러블 슈팅 목록

플레이어가 움직이지 않던 문제

  • 문제&에러에 대한 정의

Player의 조작을 위해 Input Action을 사용하였으나 플레이어가 움직이지 않았음.

  • 내가 한 시도
  1. 일단 로그를 찍어서, OnMove()가 호출되는지 확인하였음
  2. 내부 변수인 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가 비어있었다.

  • 내가 한 시도
  1. FlappyPlane.GameManager에서, 아래의 코드를 변수 부분에 추가 하였으나 실패하였다.
protected new string bestScoreKey = "FlappyBestScore";
  1. FlappyPlane.GameManager에서, void GameOver() 부분을 아래와 같이 변경하였으나 실패하였다.
public override void GameOver()
{
    Debug.Log($"key : {bestScoreKey} | score : {bestScore}");
    uiManager.SetGameOver(currentScore, base.bestScore);
}
  1. 결국, 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에서는 플레이어를 바라보는 방향을 가지도록 설정함