드로우콜

드로우 콜 : CPU가 GPU에게 어떤 것을 그리라고 명령하는 것

1. 먼저 상태가 변경됐는지(그려야 하는 상태 정보가 다른지) 확인해서 상태 변경 명령을 내리고

2. 메시를 그리라고 명령함 == DP Call

- CPU가 커맨드 버퍼에 명령을 쌓아놓고 GPU가 가져가는 방식으로 병렬 작업이 진행됨

- CPU 성능에 의존적

 

배치

배치 : DP Call과 상태 변경들을 합친 넓은 의미의 드로우 콜

 

Set Pass

Set Pass : 드로우콜이 일어날 때 상태 변경의 발생 여부

- 동일한 머티리얼을 사용한다면 메시의 변경은 포함하지 X

- 쉐이더 변경

 

배칭

배칭 : 드로우콜을 줄이는 작업

- DP Call, 상태 변경들을 묶음

 

최적화 우선순위

1. SRP 배처와 Static 배칭
2. GPU 인스턴싱
3. Dynamic 배칭

 

Static 배칭

스태틱 배칭 : 정적인 오브젝트를 위한 배칭 기법

- Project Settings - Player - Other Settings - Static Batching 체크

- 배칭할 오브젝트에 Batching Static 플래그 체크

 

 

Dynamic 배칭

다이나믹 배칭 : 동적으로 움직이는 오브젝트들끼리 배칭 처리를 하는 기법

- 배칭 처리가 런타임상에 이루어지므로 (static이 아닌 오브젝트들의 버텍스를 모아 합침 -> 다이나믹 배칭에 쓰이는 버텍스 버퍼와 인덱스 버퍼에 담음 -> GPU가 그림) 오버헤드가 발생

- Skinned Mesh에는 적용이 불가능

- 900개 이상의 버텍스 속성과 255개 이상의 버텍스를 포함하는 메시에는 적용이 불가능

 

SRP 배칭

SRP 배칭 :  URP, HDRP, SRP에서 사용하는 배칭

- 공통된 쉐이더를 사용하는 한에서 배칭이 이루어짐

- Material이 달라도 됨

- Batching은 줄지 않지만 SetPassCall이 줄어듬

 

GPU 인스턴싱

GPU 인스턴싱 : 단일 드로우 콜에서 동일한 재질의 메시 사본을 여러 개 렌더링 하는 드로우콜 최적화 기법

- 동일한 메시와 머티리얼을 공유해야함

- 다이나믹 배칭에 비해 런타임 오버헤드가 적음

- 별도의 메시를 생성하지 않고 인스턴싱되는 오브젝트들의 트랜스폼 정보를 버퍼에 담고 GPU가 이것과 원본 메시를 가져다가 한 번에 처리하여 렌더링함

 

적용

따로 적용

Static 배칭

Dynamic 배칭

- 씬에 버텍스 수가 너무 많아 프레임 디버거 사진으로 대체

SRP 배칭

GPU 인스턴싱

 

같이 적용

GPU 인스턴싱과 Static 배칭

SRP 배칭과 Static 배칭

 

결론

=> 프로젝트 상황에 맞게 드로우콜 최적화 기법을 사용하면 될 것 같다.

- 예시 프로젝트는 SRP 배칭과 Static 배칭을 합칠 때 최적화가 제일 잘 되었다.

진행한 것들

변이 버그 수정

문제점 : 변이 시 공속이 느리다는 피드백이 지속적으로 들어왔다.

원인 : 애니메이션 트랜지션이 걸려있던 문제가 있었다.

해결 : 애니메이션 Has Exit TimeTransition Duration0으로 만들어서 해결

변경 후

 

보스 안 죽는 버그 수정

문제점 : 변이 시 스위칭 과정 중 데미지가 무한으로 증가하는 버그가 있었고 이것 때문에 보스가 안 죽는 버그가 발생

원인 변이 스위칭 시 데미지 리셋을 시켜주지 않았음

해결 : 변이 스위칭 시 무조건 데미지 리셋을 시켜주도록 변경

변경 전
변경 후

 

 

내일 할 것

- 자소서 쓰기

- 발표 자료 만들기

 

 

오늘의 회고

 오늘은 유저 피드백을 바탕으로 두 번째 업데이트를 진행했다. 지속적으로 나오는 변이 공격속도를 수정하고 치명적일 수 있는 변이 데미지 증가 버그와 보스 안 죽는 버그도 수정을 했다. 금요일 발표 전 발표 자료도 천천히 준비중인데 버그가 없었으면 좋겠다. 내일도 열심히 해보자 파이팅!

진행한 것들

업데이트 반영

- 유저들의 피드백을 바탕으로 의견을 종합하여 업데이트를 진행했다.

- 모든 피드백을 수용하는 것이 아니라 기획적으로 팀적으로 의견이 일치한 부분을 반영하였다.

 

오늘의 이슈 / 내일 할 것

오늘 이슈

 

내일 할 것

- 자소서 쓰기

- 발표 자료 만들기

 

 

오늘의 회고

 오늘은 유저 피드백을 바탕으로 업데이트를 진행했다. 유저가 있어야 우리의 게임이 의미가 있어지는 것이기 때문에 유저의 피드백은 항상 소중한 것 같다. 금요일까지 발표 준비를 해야하는데 잘 정리해서 보기 좋게 만들어야겠다. 내일도 파이팅!

 

진행한 것들

유저 피드백 반영

칼날 변이 두 번째 공격 안 먹히는 버그 수정

- 문제점 : 칼날 변이 두 번째 공격이 먹히지 않음

- 원인 : 칼날 변이 두 번째 공격 애니메이션의 Animation Event가 등록되지 않았음

- 해결 : 칼날 변이 두 번째 공격 애니메이션의 Animation Event 추가

<수정 전>

 

<수정 후>

 

오늘의 이슈 / 내일 할 것

오늘 이슈

 

내일 할 것

- 자소서 쓰기

- 포트폴리오 만들기

 

 

오늘의 회고

 오늘은 유저 피드백을 받고 프로젝트 소개를 작성했다. 프로젝트를 itch.io에 올렸었는데 해외 사용자가 피드백을 준 것도 있었다. 번역을 돌리면서 게임을 플레이했고 게임에 관한 피드백을 주는데 사용자의 노력이 대단하다고 느껴 감동을 받았다. 이 피드백이 나에게 다음 스텝으로 넘어갈 수 있는 동기를 부여해줬고 내일도 열심히 하자는 다짐을 했다. 끝까지 잘 해보자 파이팅!

 

 

진행한 것들

유저 피드백 반영

점프 모션이 부자연스러워요

문제점 : 점프 모션 전공격 모션이 잠깐 나오는 버그가 존재했었다.

원인 : 공격 상태 탈출에서의 공격 취소가 제대로 되지 않았다.

해결 : 공격 상태 탈출 시 공격 취소

public abstract class PlayerAttackState : PlayerMoveState
{
    public override void Enter()
    {
        stateMachine.SetIsAttacking(true);
    }

    public override void Exit()
    {
        stateMachine.SetIsAttacking(false);
    }

}

 

점프 공격이 있었으면 좋겠어요

- 조작감이 답답하다는 피드백의 부분적인 요소 중 하나

- 팀원과의 의논점프 공격을 추가하기로 결정

 

 

오늘의 이슈 / 내일 할 것

오늘 이슈

- 프로젝트 브로셔 작성

- 피드백 반영

 

내일 할 것

- 피드백 반영

- 프로젝트 브로셔 완성

 

오늘의 회고

 오늘은 웹 출시 QA를 받아보고 게임 플레이에 지장을 주는 버그를 고치거나 다수의 인원이 공감하는 피드백을 반영해보았다. 조작감 부분에서 불편함을 느꼈고 이를 반영하기 위해 점프 공격을 추가하고 점프 모션 중 버그를 고치기도 하였다. 아직 부족하지만 기획에서 벗어나지 않는다면 계속 반영하고 고쳐나갈 생각이다. 내일도 열심히 해보자. 파이팅!

진행한 것들

구글 비공개 테스트

- 비공개 테스트 진행 (본격적인 프로덕션을 출시하기 전 비공개 테스트가 필수적임)

 

 

 

 

오늘의 이슈 / 내일 할 것

오늘 이슈

- Web 빌드 시 플레이어 공격이 여러 번 되는 버그

<기존 코드>

protected override void OnAttack()
{
        HealthSO targetSO = null;
        IDamageable damageable = null;
        Vector3 offsetVec = UpdateRayOffset();

        RaycastHit[] middle = Physics.RaycastAll(offsetVec, modelTrans.forward, _playerSO.AttackRange, layer);
        List<RaycastHit> hits = new List<RaycastHit>(middle);

        Vector3 topVec = offsetVec + new Vector3(0f, rayOffsetYMod, 0f);
        RaycastHit[] top = Physics.RaycastAll(topVec, modelTrans.forward, _playerSO.AttackRange, layer);
        hits.AddRange(top);

        Vector3 bottomVec = offsetVec + new Vector3(0f, -rayOffsetYMod, 0f);
        RaycastHit[] bottom = Physics.RaycastAll(bottomVec, modelTrans.forward, _playerSO.AttackRange, layer);
        hits.AddRange(bottom);

        hits.Distinct();
}

 

 

원인 : RaycastHit이 ValueType이라 Distinct를 하더라도 중복값 체크가 되지 않음

해결 : RaycastHit의 ReferenceType인 Collider에 접근하여 중복을 허용하지 않는 HashSet을 통해 해결

<해결 코드>

protected override void OnAttack()
{
        HealthSO targetSO = null;
        IDamageable damageable = null;
        Vector3 offsetVec = UpdateRayOffset();

        HashSet<Collider> hits = new HashSet<Collider>();

        RaycastHit[] middle = Physics.RaycastAll(offsetVec, modelTrans.forward, _playerSO.AttackRange, layer);
        AddNewRaycastHit(hits, middle);

        Vector3 topVec = offsetVec + new Vector3(0f, rayOffsetYMod, 0f);
        RaycastHit[] top = Physics.RaycastAll(topVec, modelTrans.forward, _playerSO.AttackRange, layer);
        AddNewRaycastHit(hits, top);

        Vector3 bottomVec = offsetVec + new Vector3(0f, -rayOffsetYMod, 0f);
        RaycastHit[] bottom = Physics.RaycastAll(bottomVec, modelTrans.forward, _playerSO.AttackRange, layer);
        AddNewRaycastHit(hits, bottom);
}
private void AddNewRaycastHit(HashSet<Collider> hits, RaycastHit[] middle)
    {
        foreach (var item in middle)
        {
            Collider collider = item.collider;
            if (!hits.Contains(collider))
                hits.Add(collider);
        }
    }

 

내일 할 것

- 웹 QA 피드백 반영하기

 

 

오늘의 회고

 오늘은 구글 플레이 스토어에 앱 정보를 등록했다. 우리가 개발한 프로젝트에 해당되지 않는 질문들이 많았고 그거 보는 재미도 있었던 것 같다. 그리고 생각보다 이미지 규격이 까다로웠는데 아마 모바일에서 해상도를 맞추느라 제한이 있는가보다 하고 생각했다. 내일은 웹 배포 한 것을 바탕으로 유저 피드백을 반영할 생각이다. 내일도 파이팅!

진행한 것들

Itch.Io 배포

- Itch.Io에 먼저 배포를 시도 했습니다. (알파 버전)

 

 

오늘의 이슈 / 내일 할 것

오늘 이슈

- 발판 버그, 엘레베이터 버그

 

 

내일 할 것

- 웹 QA 시도하기

 

 

오늘의 회고

 오늘은 웹 배포를 했다. 웹 배포는 구글 플레이스토어 출시와는 다르게 굉장히 쉬웠던 것 같다.(itch.io 기준) 해상도와 앱의 규격만 맞춰주면은 알아서 올라가고 유저가 쉽게 바로 테스트 해 볼 수 있다는 점이 장점으로 다가왔다. 내일은 구글 비공개 테스트를 진행할 것인데 유저들이 부디 재밌게 플레이 해줬으면 좋겠다. 내일도 파이팅!

진행한 것들

메인 씬 보스 적용

- 보스를 메인 씬에 적용하였습니다.

 

 

오늘의 이슈 / 내일 할 것

오늘 이슈

- 수류탄 / 로켓 위치 버그

문제점 : 중간의 랜덤 y 위치가 0으로 고정되어 있다.

원인 : 이전의 테스트 씬에서 적용할 때보다 메인 씬의 y 위치가 낮아서 생기는 경우였다.

해결 : 타겟의 y 위치를 기준으로 더 낮으면 더 높게 설정하도록 수정하였다.

 

 

내일 할 것

- 빌드 후 구글 플레이스토어 연동하기

 

오늘의 회고

 오늘은 메인 씬에 보스 연결하는 작업을 진행했다. 빌드 전 버그를 많이 수정했는데 로켓과 수류탄의 베지어 곡선에서의 중간 y 위치가 잘못되어 있는 버그, 드론 폭탄 오브젝트가 재사용 될 때 안 보이는 버그, 재시작할 때 변이 Null 뜨는 버그 등 여러가지 버그를 수정했다. 내일은 배포를 해야하는데 최대한 버그를 잡고 나서 배포할 계획이다. 내일도 열심히 해보자. 파이팅!

진행한 것들

보스 근접 공격 / UI 적용

- 보스 근접 공격 : 플레이어가 가까이 왔을 시 근접 공격을 합니다.

- 보스 UI 적용 : 보스의 체력, 쿨타임 표시

 

 

오늘의 이슈 / 내일 할 것

오늘 이슈

- 수류탄 위치 버그

문제점 : 수류탄이 생성될 때의 위치에서 날라간다.

원인 : 모델을 SetActive(true)하는 시점이 스킬을 사용할 때다. 그런데 애니메이션이 끝날 때 던지기 때문이상하게 보인다.

해결 : 모델 SetActive(true) 시점을 던질 때로 바꿨다.

 

 

내일 할 것

- 보스 등장 연출

- 보스 맵 트리거 시 보스 초기화

- 보스 공격 사운드 적용

- 보스방 폐쇄 / 개방 구현

 

오늘의 회고

 오늘은 보스 상태를 UI와 연결하고 플레이어가 보스의 가까이 왔을 때 근접 공격을 하도록 만들었다. 하나 하나씩 보스에 대한 부분을 추가하니 이제 꽤 쓸만해 보이는 것 같다. 이번 프로젝트도 잘 마무리해서 후회 없도록 해야겠다. 내일도 파이팅!

진행한 것들

페이즈 2 - RPG 타겟 표시

- RPG가 어디로 날아갈 지 타겟을 표시하고 터지게 만듬

 

 

페이즈 3 - 드론 폭탄 투하

- 드론이 맵 위를 날아다니면서 폭탄을 투하하고 플레이어가 맞았을 시 데미지를 줌

 

 

오늘의 이슈 / 내일 할 것

오늘 이슈

- 드론 폭탄 이펙트 사라지지 않음 - EffectPool 문제

 

내일 할 것

- 보스 체력 / 페이즈 / 쿨타임 UI 연결

- 근거리 공격 구현

 

 

오늘의 회고

 오늘은 RPG 유도 미사일의 타겟을 표시하는 것과 드론 폭탄이 떨어질 때 데미지를 주고 이펙트를 보여주는 것을 구현했다. 어렵진 않았지만 지금 작업 중인 보스 UI 연결은 이벤트 방식으로 구현할 생각이라 조금 시간이 걸리는 것 같다. 내일 오전 중에 마무리 하도록 해보자. 내일도 파이팅!

+ Recent posts