우선 지금은 마인크래프트처럼 블록단위로 나눠서 구현중인데

현재 목표는 marching cube 또는 감당이 된다면 블록을 다시한번 3x3x3으로 나눠서 너무 심한 네모네모에서 벗어나는거임

오늘 자면서 고민해봐야지.


만들고싶은건 재해? 재앙에서 살아남는 류의 게임.

어찌될지는 모르겠다만 일단 시작함


당연히 청크와 펄린 노이즈를 기반으로 구현했는데, 펄린 노이즈는 어차피 나중에 랜덤 지형 생성하는 단계에서 연구하고 손볼거라 지금은 대충 해둠.



viewimage.php?id=2abcdd23dad63db0&no=24b0d769e1d32ca73ced8ffa11d02831dfaf0852456fb219302713c4cc81ae38d1ea4af2b4c14d0b9b60e61df0ed34549e6f312aa989b042cdb33db019ea13

허접해보이지만

일단은 청크를 하드디스크에서 로드, 언로드하는부분까지 구현함

3D에 대해 아무것도 모르는 상태라서 생각보다 어려웠음..




청크 로드 or 생성


청크 정보 리스트에 데이터가 하드디스크에 있는지를 청크 정보 리스트에 넣어두고,

나중에 "이 청크를 로드할까 생성할까?"하는 분기에서 청크 정보 리스트 안을 체크하..려고 했었음.

근데 이걸 효율적으로 하기 위해선 단순히 리스트에 담아두는걸로는 안되고 어떤 방식이던 정렬을 해둬야 함. 그래야 빠르게 찾으니깐


청크 ID가 벡터3이라서

x -> y -> z 순서로 오름차순 정렬을 했고 이진탐색 및 이진삽입을 응용해서 하려했는데 버그때문에 멘탈이 나가고, 사실 오랜만에 다시 시작한거임.

작업하던거 폐기하고, 그냥 리스트에 담긴 정보에서 순서대로 for문으로 찾음.

근데 디렉토리에서 File.Exists()하는거랑 별반 차이가 없길래, 리스트에 정보같은거 담지 않고 그냥 직접 디렉토리에서 직접 이 청크가 존재하는지 검사하도록 해뒀음

나중에 이건 적합한 방법이 생각나면 수정할거임.

지금은 마인크래프트처럼 청크를 다시한번 region으로 분류해서 저장해둠


당연히 청크로드와 세이브는 스레드로 처리함



-청크-


우선 청크 안에는 "블록"3차원 배열이 들어있음

배열의 크기는 32x32x32. 청크 크기가 32 32 32라 보면 됨


청크는 벡터3 ID로 관리됨

(Mathf.FloorToInt(x / 32), Mathf.FloorToInt(y / 32), Mathf.FloorToInt(z / 32))


-메쉬 생성-


청크 메쉬를 만드는게 쉽다면 쉽고 어렵다면 어려운 작업이였는데 제대로 구현한건진 모르겠다.

청크 업데이트가 많이 일어날 때 스레드에서 돌리는데도, 1000프레임 에서 200프레임까지 떨어지던데 불안함.

좋은 방법 있으면 알려주면 좋겠다.




블록의 포지션을 넣어주면 vertices리스트에 필요한 꼭지점을 넣고, 그 꼭지점을 이용해 삼각형을 만들어줌

block은 나중에 여러 종류의 블록을 넣을 때 uv 잡아주려고 넣어둠. 지금은 단일블록이라 안씀


참고로 pos는 정수이고, 0,0,0 pos이면 0,0,0~1,1,1에 있는 블록을 의미함


viewimage.php?id=2abcdd23dad63db0&no=24b0d769e1d32ca73ced8ffa11d02831dfaf0852456fb219302713c4cc81ae38d1ea4af2b4c14d0bdf35b3199ae93053c8124bd157b55e65a3d2888115dcc80b7274c07b


여기서 의문인게 32x32x32블록을 전부 순회하면서 메쉬를 업데이트 시켜주는게 과연 성능상 괜찮은 일일까?

근데 어차피 블록 추가/삭제할 때 청크 하나만 업데이트할테니 상관 없을듯


현재는 블록에서 왼쪽 블록이 비어있다면 왼쪽 면을 메쉬에 추가, 왼쪽에 다른 블록이 있다면 추가하지 않는 방식으로 구현함

renderInfo는 왜 넣었는지 기억 안나지만 지금단계에선 안씀.


viewimage.php?id=2abcdd23dad63db0&no=24b0d769e1d32ca73ced8ffa11d02831dfaf0852456fb219302713c4cc81ae38d1ea4af2b4c14d0bdf35b3199ae93053c8124bd157b55e65f58283dc17d89b59a2f96c57

viewimage.php?id=2abcdd23dad63db0&no=24b0d769e1d32ca73ced8ffa11d02831dfaf0852456fb219302713c4cc81ae38d1ea4af2b4c14d0bdf35b3199ae93053c8124bd157b55e65a8828f8a178f9d0e7baa09ac

지금껏 이 단계가 렉의 원인일거라 생각했는데, 알고보니 업데이트 할때마다 메쉬를 새로 생성시켜서 렉걸렸었음.

기존 메쉬의 꼭짓점, 삼각형 등의 정보를 덮어쓰는것만으로도 메쉬가 바로 업데이트 되더라.


이 부분도 스레드로 돌리는데 렉걸려서 이상하다 했어.


메쉬 생성에서 최적화를 시키고 싶은데 방법이 생각나질 않는다



-청크의 업데이트-


첫 로딩은 전부 로드시켜주고, 게임 중에는 이동한 방향으로 최소한의 청크만 로드시켜줌


청크 로드 거리와 메쉬 로드 거리가 별도로 존재함.

청크 로드 거리안에 들어온 청크는, 하드디스크에서 로드해오고(또는 생성하고), 메쉬 로드 거리 안에 들어오면 메쉬를 생성해냄.

사실 이건 필요한 작업인지는 모르겠으나,

하드디스크에서 로드해오는 시간, 데이터를 생성하는 시간이 지나치게 길 경우를 고려해서

메쉬를 생성하는 단계에서는 이미 데이터가 로드되어있도록 하는 작업임.


프로그래밍을 하다보니 일어나지도 않은 상황을 가정해서 대비하게 되더라





플레이어가 움직여서 현재 속한 청크ID가 바뀌었으면 이동 벡터를 구함


예를들어 이동벡터가 x방향으로 1이면

현재청크 + 청크로드거리(x방향)에 위치한 모든 청크를 업데이트 시켜주고

청크 - 청크로드거리(x방향) - 1에 위치한 청크를 언로드 시켜줌. 이제 다시 이 청크에 접근하려면 하드디스크에서 불러와야 함.


청크 로드거리가 3이라면 7x7 정사각형 범위의 청크들이 로드되고, 10이라면 21x21 범위의 청크들이 로드됨.


viewimage.php?id=2abcdd23dad63db0&no=24b0d769e1d32ca73ced8ffa11d02831dfaf0852456fb219302713c4cc81ae38d1ea4af2b4c14d0bdf35b374f6ea37521b108ba439af77816466d100b1aea5fa692aa5


청크 메쉬 로드


위와 마찬가지인데, 하드디스크에서 로드하는 작업 대신 메쉬를 생성해주는 작업

사실 메쉬를 생성한다고는 하는데 메쉬를 담고있는 청크 오브젝트를 여기서 생성해주고 파괴해줌.



방학하고 한달가까이 게임만하고 놀다가 오랜만에 다시 개발 시작함.

오늘부터 꾸준히 해서 개발일지 올림