노트 최적화

오버랩은 레이어 마스크로 지정된 Collider를 찾는 메서드이다. IsTrigger를 사용할 경우, 노트가 너무 빠르면 감지가 안되는 경우가 있기 때문에 최적화를 위해  처음엔 RigidBody 대신 오버랩(Overlap)을 사용하려했다.

그런데 아예 노트와 노트 판정하는 위치의Transform 값을 받아와서 비교하면  Collider를 사용하지 않고 할 수 있었다.

 

노트를 리스트에 추가하기 위해 TimingManager 스크립트와 GetComponent로 연결하는데 연결이 되지 않고 null 값이 떴다. GetComponent는 자기 자신을 가져오는데 Note 스크립트와 TimingManager 스크립트가 같은 오브젝트에 있지 않았기 때문이었다.

Find 메서드를 사용하여 해결하였다.

public class Note : MonoBehaviour
{
    [SerializeField] private NoteMove noteMove;
    public KeyCode key;
    private Color color;
    TimingManager timingManager;
   

    private void Awake()
    {
        color = GetComponent<SpriteRenderer>().color;
        timingManager = FindObjectOfType<TimingManager>();

    }

    public void NoteCreate()
    {
        NoteMove note = Instantiate(noteMove, transform.position, Quaternion.identity);
        note.GetComponent<SpriteRenderer>().color = color;
        note.noteSpeed = PlaySetting.speed;
        
        timingManager.boxNoteList.Add(note.gameObject);
    }
}

 

트러블 슈팅

게임 플레이 도중 일시정지하거나 재시작 하는 기능을 추가하기로 했는데 노래 선택해서 플레이 하면서 일시정지 후, 게임을 나갔다가 다시 들어오면 게임 플레이 화면이 로딩되지 않는 현상이 있었다.

일시정지 기능을 Time.timeScale = 0으로 구현했는데 그 후에 다시 시간이 흐르도록 처리하지 않아서 생긴 문제였다.

 

VideoPlayer가 안보일 때

리듬 게임을 재생하면 노트 UI 뒷부분에서 비디오가 재생되도록 했는데 안보인다.

Video Player 설정을 보니 Render Mode가 Render Texture로 되어있었다.

Render Texture는 오브젝트의 텍스쳐에 붙여주어야하기 때문에 타겟 오브젝트가 존재해야한다.

 

2D게임이기 때문에 그냥 메인 카메라에서 가장 멀리 보이는 화면으로 설정했다.

 

잘 보인당ㅍvㅍ

Update()와 FixedUpdate()의 차이

  • Update : 매 프레임마다 호출되는 메서드. 게임 로직의 주요 업데이트가 이루어진다. 매 프레임 호출되는 만큼 불필요한 계산을 피하고 최적화하기 위해 사용하지 않으면 지워주는 것이 좋다.
  • FixedUpdate : 물리 엔진 업데이트 시 호출되는 메서드. 물리적인 시뮬레이션에 관련된 작업을 처리할 때 사용된다. Fixed Timestep에 설정된 값에 따라 일정한 간격으로 호출된다.

스크립트 라이프 사이클

 

Update는 불규칙한 호출임으로 물리엔진 충돌검사 등이 제대로 안될 수 있기 때문에 물리적인 시뮬레이션에 관련된 작업을 처리할 때는 FixedUpDate를 사용하는 것이 좋다.

 

리듬게임의 노트에 판정을 위한 Collider가 붙어있으므로 FixedUpDate를 사용한다.

private float noteSpeed;

private void FixedUpdate()
{
    Move();
}

private void Move()
{
    transform.position += Vector3.down * noteSpeed * Time.fixedDeltaTime;
}

 

 

노트의 정확한 판정을 위해 double을 사용하면 어떨까 해서 적용해보니 Vector3 및 double 형식의 피연산자에 적용할 수 없다고 뜬다.

float에 비해 double의 소수점 범위가 더 크기 때문에 발생하는 문제가 아닐까 예측했는데 double의 연산자 오버로딩이 없어서 그런 것이었다. 즉, 유니티에서 Vector3에 곱하는 방법을 명시하지 않은 것이다.

 

 

<Wire Frame>

게임 컨셉은 아쿠아리움으로 노래를 Perfect 등급으로 깰 때마다 새로운 물고기를 얻는 방식으로 계획했다.

 

 

<구현 계획>

  • 노트 생성
    • 여러 곡의 리듬에 맞는 노트 생성
    • 일정 게이지 이상 노트 획득 시 아쿠아리움 내에 먹이 생성
    • 오브젝트 풀링 활용
  •  아쿠아리움 구성
    • 물고기 인벤토리씬 : 물고기 장착 해제 시 맵 내에 물고기 활성화/비활성화
    • 물고기의 움직임 구현 / 애니메이션 또는 AI로 구현해 보기
    • 어항 크기 조절 < 시간이 남으면 추가로 구현
  • 리듬 게임 페이즈
    • 노트가 떨어지는 트랙 생성
    • 노트와 판정선 사이의 충돌 판정(Perfect,Great,Good,Bad,Miss)
    • 콤보 정보 기록(UI 연동)
  • UI / UX
    • 노트 히트 콤보 기록
    • 점수 기록
    • LIfe 게이지 기록
    • 물고기 먹이 게이지
  • 게임 엔딩 조건
    모든 곡을 퍼펙트로 클리어하여 전설의 물고기 모두 수집 시 게임 엔딩/ 고래 수집

나는 노트 생성 부분을 맡았으며 오브젝트 풀 방식을 완벽히 이해하고 사용하여 코드적인 부분 어필하는 것이 목표이다.

 

 

+ Recent posts