개인적으로 주어진 업무에 맞춰 RnD를 진행한다


플레이어

사실플레이어는 어려울 것이 없다. 프로토타입을 빠르게 직접 구현하는 것을 목표로 한다. 플레이어의 정보는 Scriptable Object로 만들어 관리한다. 플레이어에 해당하는 캐릭터 모델 또한 Scriptable Object로 만들어 관리한다. 그러한 정보들을 리스트로 가지고 있고, 선택해서 적용할 수 있게 한다.
OnEnable에서 오브젝트 풀 탄약 생성, OnDisable로 파괴한다. 해당 기능은 ObjectSpawner 또는 ObjectPool에서 구현

카메라 고정

씬에서 카메라는 고정된 상태로 있는다. 움직이는 것은 밑에서 스크롤되는 맵, 플레이어 등 카메라를 제외한 모두.

이동

Trnasform을 기반으로 이동하지 않는다. Rigidbody.velocity를 사용해서 움직이도록 한다.

발사

InputSystem으로 발사 버튼을 누르면, 총알 프리팹으로 이루어진 ObjectPool에서 대여해서 생성. AddForce(Impulse)로 앞으로 이동시킨다. 총알은 Bullet을 상속받는다.

회피

회피는 플레이어의 이동으로 구현되는 기능. 회피관련 Input은 없다.

아이템(폭탄 등) 사용

발사 버튼처럼 아이템 사용 버튼을 준비. 아이템 사용 버튼을 누르면, 현재 소지중인 아이템이 사용된다. 또는 폭탄 버튼과 분리할 수 있다. 아이템은 UI상으로 표시되게 한다.

(패링)

옵션에 해당한다. 일단 주석으로 이 자리에 기능이 들어갈 것이다 라는 표시를 해놓는다

아이템 소지 / 습득

OnCollisionEnter에서 collision이 적의 포탄(layer)일 경우 피격, 아이템(layer)일 경우 아이템 소지로 처리한다. 재화를 습득하는 방식도 같은 방법이다.


총알

플레이어가 발사하는 총알에 대한 처리다

Bullet

ScriptableObject 클래스. 플레이어의 총알은 클래스로 Bullet을 상속받아서 구현한다. Bullet이 가질 정보들을 이곳에서 미리 선언해둔다. 본인이 돌아갈 Pool에 대한 정보를 필드로 가진다. List로 Prefab 을 만든다. 총알의 모델로 쓰일 것들을 여기에 지정할 수 있다. (ObjectPool<Bullet>)에 해당하는 ObjectPool 필드를 가진다. 본인이 되돌아가야 할 Pool을 지정할때 쓰인다.

Player Bullet

Scriptable Object를 Bullet을 통해 생성한다. 플레이어가 발사하는 총알이다. Bullet을 상속받아서 구현한다. 발사하는 총알의 타입이 여러가지이므로 Player Bullet1,2,3과 같이 구현한다.

BulletController

Scriptable Object Bullet을 필드로 가진다. MonoBehaviour를 상속받는 Game Object다. 오브젝트 풀에서 해당 컴포넌트를 참조한다. Awake에서 Bullet Controller의 필드를 Bullet에서 전부 복사한다. 함수로 Recall(스크립터블 오브젝트에서 다시 정보 가져오기), DestroyObject(게임 오브젝트 파괴하기)를 가진다.

무기 변경

무기 레벨업 또는 무기 변경 시 필요한 기능. Bullet 프리팹을 변경 후, ObjectPool을 재생성한다. 또는 캐릭터 변경으로 인한 무기 교환 방법이면, 자동으로 변환된다. ObjectPool 생성이 OnEnable에서 이뤄지기 때문.


Object Pool

오브젝트 풀

지정한 오브젝트(T)를 Stack으로 가진다. OnEnable에서 들을 생성하고 돌아갈 Pool을 지정해놓는다. 함수로는 ObjectPool 인스턴스 생성. ObjectPool 인스턴스 파괴를 가진다. 해당 게임 오브젝트에는 T로 호환되는 것들이 올 수 있다.

OjbectSpawner

Player 및 Enemy등, Ojbect Pool을 가질 수 있는 게임 오브젝트는 해당 스크립트를 컴포넌트로 가진다. 미리 만들어놓은 Pool에서 하나 꺼내는 것 까지 구현된다. 반납조건을 설정할 수 있다.

PlayerObjectSpawner

ObjectSpawner를 상속받는다. T 프리팹으로 Bullet을 받는다. Bullet에 대한 오브젝트 풀 생성하고, 풀에서 꺼내와 사용할 때 AddForce 시켜서 앞으로 탄약이 이동하게 한다. 일정시간이 지나거나 충돌하면 반납할 수 있게 구현한다. 지상 적의 경우, 지상 적의 판단으로 해당 기능을 수행해야 하기 때문에, 반납을 public으로 열어둔다.


UI

UI특강

UI Binding

UI를 에디터 상에서 찾을 필요 없이, 스크립트 상에서 편집할 수 있게 설계한다. 딕셔너리를 통해 UI 요소들을 저장한다.

UI Manager

매니저로 UI를 다루기 쉽게 설계한다. 공통적인 기능을 수행하는 것들은 함수로 따로 만들어 처리한다.

UI PopUp

설정창, 파티구성 창과 같이 씬 전환없이 이뤄지는 팝업 UI를 설계한다. Resources 폴더에 따로 UI들을 저장해서 사용한다.


피드백

금일 프로젝트 설계 및 R&D중 부족한 부분이나 질문사항들에 대해서 기록한다.

유도미사일

적에게서 발사되는 탄막이 유도일 경우, 어떤식으로 구현할지에 대한 질문.
1. NavMesh, a*알고리즘을 통한 길찾기로 플레이어 추적.
2. MoveTowards(각도)를 통해 자연스럽게 플레이어 추적(벽에 막힐 수 있음)
3. 다른방법?

일단 2번이 가장 현실적인 방법이 될 것 같다. 추후 기획팀에서 나오는 기획안에 따라(기획이 원하는 방향에 따라) 변경될 수 있다. 프로토타입을 만든 후, 보여주는 것이 좋을 듯 하다.

지상의 적 공격

지상에 있는 적에게 플레이어의 공격이 닿게(충돌) 하려면 어떻게 해야 되는가?

위와 같이 화면상에서 플레이어의 공격이 적에게 닿는것 처럼 보여도 실제로는 안맞는다. 이를 위해 고려해볼 만한 방법은 아래와 같다.

WorldToScreenPoint

카메라를 기준으로 좌표를 생성해서, 플레이어의 탄약과 적의 위치를 스크린 기준 좌표로 변환한다. 이후, 둘의 거리를 계산해서 만약 일정 거리 이하일 경우 맞은것처럼 처리한다.

계산방법

Bullet은 public 필드로 스크린 상 좌표를 가진다.
1. Enemy는 Update마다 foreach(플레이어 탄약 위치좌표in 플레이어 탄약 스택)를 돌린다. if(두 좌표의 차이<일정거리) { 피격 판정}. Bullet의 반환은 Bullet의 정보를 받아와서 수행한다.
2. 발사되는 모든 Bullet은 Update마다 foreach(적 스크린좌표 in 모든 적)를 수행. 특정 적과 일정거리 이하일 경우, 피격으로 판정. Bullet은 그대로 반환 수행. 적 정보를 가져온 후 적.Hit 함수 수행.
3. 발사되는 모든 Bullet은 업데이트마다 OverlapSphere를 수행해서 layer = 적이 검출되면 피격 판정 수행.

그 외 방법


지상 적의 콜라이더를 카메라 방향으로 늘리고, 업데이트마다 카메라 방향으로 회전시킨다. 그러면 콜라이더에 총알이 부딪힐 수 있다. 이 방법이 가장 현실적

profile
개발 박살내자

0개의 댓글