1/12
Looks like no tags are added yet.
Name | Mastery | Learn | Test | Matching | Spaced |
---|
No study sessions yet.
플레이의 자유도를 높인다는것은?
해당 장르에서 여러 시도가 있다는걸 안다. 공포와 재미를 높이기 위해서 플레이어를 완전히 제약하는 방향과, 풀어주는 방향 중 풀어주는 방향을 선택했다. 왜? 변칙적인 재미를 주기 위해서. 그래서 시스템을 추가했다. 가장 고정되어있는 요소인 벽을 이동함으로써 플레이어가 움직일 길을 만들거나 몬스터를 가로막고, 그 선택에 따라 결말까지 이어지는 길을 자유롭게 선택하게 하기 위함이다.
맵 구조 변경 시스템이란?
맵 곳곳에 이동 가능한 벽과 이동 불가능한 벽을 지정해뒀다. 외벽같은 경우는 완전히 이동 불가능하지만, 방과 방을 구분하기 위한 벽들의 핵심 위치는 이동 가능한 벽들을 배치했다. 그리고 특수 아이템인 망치를 획득했을 때 기능이 활성화된다. 벽 액터및 그 하위 요소들을 모두 플레이어 카메라의 하위 요소로 집어 넣음으로써 플레이어의 시야와 함께 움직일 수 있도록 구성했다.
왜 이런 구조로 만들었나? 개선하고 싶은 점은?
맵 구조 변경 시스템을 구성할 때, 가로세로를 맞춰서 크래프팅 하듯 만드는 방법도 생각해봤으나, 플레이어가 급하게 옮긴 벽이 몬스터를 막아내지 못하는 장면을 넣고 싶었기에 자유로운 장소에 벽을 배치할 수 있도록 구현했다.
벽을 옮기고 내리는 과정에서, 모든 하위 요소들의 콜라이더를 활성화, 비활성화 했다. 다시 작업한다면 이들은 놔두고, 가장 바깥을 포장하는 외부 박스 콜라이더를 지정한 다음 이것만 활성화, 비활성화 할 것. 당시에는 우선 각 요소들 또한 충돌을 해제해야한다는 생각으로 이렇게 작업했던 것 같다.
플레이어 행동 및 정보 제어에서 문제? 해결?
벽이 하나의 액터가 아니라 여러 요소로 구성되어있었다. 기존의 벽 옮기기 기능은 Raycast에 닿은 물체 하나만을 판별해 이동했고, 벽의 일부만 옮겨진다는 문제가 있었다. 이를 해결하기 위해서 토의를 했고, 여러 물체를하나로 합쳐달라고 맵 개발자에게 요청했다. 그러나 결과물이 생각과는 달랐다. 외부 빈 오브젝트로 이를 감싼것. 그리고 정작 레이캐스트에 닿는 부분은 이전과 동일했다.
맵 개발자는 따로 해결해야하는 업무가 있었고, 결국 내가 맡아서 인식 구조를 변경했다. 그때 생각했던 해결법은 부모 오브젝트를 찾고, 그 오브젝트의 태그가 움직일 수 있는 벽인 경우 동작을 진행하는 것이었다. 이를 기반으로 정보 표시, 행동 구조를 변경하였으며 문제를 해결할 수 있었다.
플레이어 행동 제어 성과
여기서 얻은 것은?
의사소통을 할 때는 보다확실하게 내가 원하는 바를 구체적으로 설명해야한다는 것. 단순히 말로만 전달했다가는 생각했던 것과 다른 결과물을 받을 수 있다.
성과는?
우선 클래스 분리를 통해서 유지보수가 좀 더 쉬워졌다. 그리고 기존에 정보 제어 과정에서 매 틱마다 모든 정보를 갱신했었는데, 데이터가 변경되었을 때만 이를 갱신하도록 변경하여 불필요한 함수 호출을 줄일 수 있었다.
지금 생각해보면 어떻게 할 수 있나?
다시 생각해보면 매우 간단하게 해결할 수 있는 문제였다. 애초에 외부 요소로 한 겹 씌운 것이 벽과 다른 위치에 있어서 생각하지 못했었는데, 벽을 커버하는 형태로 사각형을 배치하고 여기에 Laycast가 닿게 했으면 기존 구조를 변경하지 않고도 해결할 수 있었다. 그게 아쉽다.
Raycast 처리 신경쓴 부분
Raycast로 정보를 처리하는 부분에 신경을 썼다. Raycast결과를 바탕으로 행동과 정보를 제어하는 부분이다. 기존에는 Update()함수에서 매 틱마다 모든 갱신을 진행했지만, 이전상태와 현재 상태를 비교하여 변경이 확인되었을 때만 다른 함수가 호출되도록 했다.
아쉬운 점도 있다
함수 호출 총량을 줄이기는 했는데, 조금 이상하게 되었다. Raycast쪽에서 조건 만족을 확인하고, 그 경우에 InfoControll을 호출했으면 Update()의 부담을 줄일 수 있었을텐데. Raycast는 진짜 정보만 얻고 InfoControll에서 별도로 Update를 사용하여 이 정보를 분석해 사용해 사용했다. 조금 결합을 높이더라고 저쪽이 효율적이지 않나?
정보 처리부분은 어떠한가? 두 가지 요소를 중심으로 생각했다. 광선 자체가 충돌중인지, 그리고 충돌중인 물체가 바뀌었는지. 이 두 가지 요소에 따라서 경우를 나누었으며, 각각 다른 동작을 진행하도록 구성했다.
싱글톤 왜썼냐
싱글톤 패턴 자체는 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고, 이후 호출된 생성자는 이 객체를 리턴하도록 하는 구조이다.
이걸 사용한 이유는 여러 사운드 리소스를 한 곳에서 모아 관리하려는 사운드 매니저의 설계 목적상 추가적인 인스턴스 생성이 없는 싱글톤이 적합하다고 생각했기 때문. 어디서든 사운드 매니저에 접근할 수 있고, 사운드 리소스 중복 문제를 해결할 수 있다.
어떻게 만들었냐? 이 클래스에서 전역변수로 자신의 Instance를 선언했다. 그리고 Awake함수에서 비어있으면 스스로를 지정하고, 아니면 스스로를 파괴하도록 한 것. 이 사운드가 필요한 각 요소들은 사운드 매니저 포인터를 생성하고, 여기의 함수를 호출하여 사운드를 재생한다. 사운드를 재생하기 위한 풀은 미리 몇 개를 고정으로 해두었다.
싱글톤 중요하게 생각한거
어떻게 보면 밀봉하는 부분이 중요한거 아닐까. 어떻게 해서든 외부에서 생성하거나 변조하는 것을 방지해야한다. 이를 위해서 생성자를 private로 만들어 외부에서 만들 수 없도록 하거나, 복사나 대입과 같은 방식으로 접근하는 것 또한 막아둬야한다.
싱글톤 메모리관리 어떻게?
우선 이 사운드 매니저 프리팹에 사운드 요소들을 넣어두었다. 구현 당시에는 그저 싱글톤을 사용하여 추가적인 생성을 방지하고, 메모리를 적게 유지하는 것에 관심을 두었다. 다시 생각해보면 그 사운드 요소들을 별도로 분리하고, Laze Initialize로 싱글톤 확정 이후 호출하도록 하는게 메모리 관리에 더욱 도움이 되지 않았을가 생각한다.
아쉬웠던 부분?
그러니까, 뭐 서로 데이터간 연결이 있다면 이걸 직접 연결할건지, 아니면 에디터에서 가져와 연결할건지. 그런 논의가 부족했다. 그래서 서로 작업물을 합칠 때, 누구의 패키지를 사용하냐에 따라서 작업 내용이 날아가는 경우가 종종 있었다. 미리 합의해두고 코드를 어떻게 작성해야하는지 정해두었으면 좋았을 것.
오픈소스 협업 가이드라인?
2021년도에 종료된 프로젝트로, 유니티에서 진행한 Chop-Chop이라는 오픈프로젝트가 있다. 여기 기여 가이드 라인이 있는데, 여기서 주로 금지 사항들을 참고했다. 패키지 추가, 기존 패키지 업데이트 금지, 버전 업데이트 금지 등을 하고, 기여 방법은 좀 다르게 해서 notion 중심으로 버그 및 작업 내용을 업데이트했다. 연락은 카톡으로 하고. 이런 점에서 차이가 있었다. 그리고 주기적으로 작업 내역 병합 및 발표를 거친 것.
→ 정말 기초적인 것이지만 이게 지켜지지 않아서 문제가 생겼었기 때문에, 특히 패키지 업데이트. 그래서 참고한게 도움이 되었다. 그리고 지켜지지 않은 것도 있는데, 테스트 스크립트 푸시하지 말라는거, 이게 가장 안지켜졌다.
최적화 경험??
→ 유니티 엔진에서 제공하는 기본 최적화들을 사요했다. 라이트 베이크, 오클루전 컬링 등. 아무래도 실내 공간이고 벽에 감싸인 건물이다보니 오클루전 컬링을 사용했을 때 성능이 크게 개선되었다.
오클루전 컬링에 대해 설명해주세요
→ 다른 오브젝트에 가려져 화면에 완전히 가려진 오브젝트들을 렌더링 대상에서 제외하는 최적화 기법이다. 불필요한 드로우콜을 감소시킬 수 있다. 하지만 얼마나 촘촘하게 대상이 보이는지 판별할것인가 중요. 창틀 바깥이 보이는 수준까지 만들어두고 했다.
VOWRA 문제?
VOWRA 프로젝트에서 VR 환경의 3D 의료영상 상호작용 기능을 구현하면서 겪은 어려움과, 해결 방법은 무엇인가요?
→ 기술적인 문제가 있었다. 노트북에 연결했을 때, 노트북이 내장 및 외장 그래픽카드를 자동으로 변경하는 기능이 있는데, 내장으로 연결되던것. 그래서 최소 요구사항에 못미치니까 그레이 스크린이 발생. 노트북의 한쪽 그래픽카드를 아예 비활성화 시킨 후 연결하니 정상 작동.