내일배움캠프 Unity 58일차 TIL - 팀 9와 4분의 3 - 개발일지

Wooooo·2024년 1월 17일
0

내일배움캠프Unity

목록 보기
60/94

[오늘의 키워드]

  1. NavMeshBuildSource 리스트 갱신 로직 최적화
  2. Slide Block 추가
  3. 해야할 것 정리

1. [NavMeshBuildSource 리스트 갱신 로직 최적화]

기존

    /// <summary> 시야범위 내의 청크 생성 </summary>
    public void UpdateChunksInViewRange()
    {
        _prevActiveChunks = _currentActiveChunks;
        _currentActiveChunks = new();

        for (int x = -WorldData.ViewChunkRange; x <= WorldData.ViewChunkRange; x++)
        {
            for (int z = -WorldData.ViewChunkRange; z <= WorldData.ViewChunkRange; z++)
            {
                if (_chunkMap.TryGetValue(_currentPlayerCoord + new ChunkCoord(x, z), out var currentChunk))
                {
                    _currentActiveChunks.Add(currentChunk);
                    currentChunk.SetActive(true);
                    _prevActiveChunks.Remove(currentChunk);

                    // NavMesh Source 전달
                    _navMeshBuilder.UpdateChunkSources(_currentActiveChunks);
                }
            }
        }

        foreach (var chunk in _prevActiveChunks)
            chunk.IsActive = false;

        _navMeshBuilder.UpdateNavMesh();
    }

기존에는 청크가 활성화 될 때마다 WorldNavMeshBuilder 클래스에게 source를 갱신하도록 요청하고 있었는데, 이 로직의 문제가 있었다.

활성화되는 청크가 여러개일 경우, source 갱신의 요청도 여러번된다. 불필요한 연산이 발생하는 것이다.

변경 후

    public AsyncOperation UpdateNavMesh(Action<AsyncOperation> callback = null)
    {
        UpdateChunkSources(Managers.Game.World.CurrentActiveChunks);

        if (_data == null || _sources == null)
            return null;

        var buildSettings = NavMesh.GetSettingsByID(0);
        var bounds = CalculateViewBounds();
        var op = NavMeshBuilder.UpdateNavMeshDataAsync(_data, buildSettings, _sources, bounds);
        op.completed += callback;
        return op;
    }

WorldNavMeshBuilder 클래스에서 source의 변경을 클래스 외부에서 따로 하지 않고, nav mesh의 갱신 요청만 받도록한 다음, nav mesh 갱신 시 source도 함께 갱신하도록 구조를 변경했다.


2. [Slide Block 추가]

우리 프로젝트 캐릭터에 점프는 추가하지 않을 예정이다.
하지만 맵은 Voxel 큐브 형태라서, 플레이어 캐릭터가 y축 이동을 할 수단이 필요하다.

좌측 섬, 우측 섬에는 산도 추가될 예정이기 때문에 오르락 내리락 할 Block을 추가했다.

스크립터블 오브젝트로 여러가지 Material을 설정할 수 있도록 했다.
현재 구현돼있는 일반 Block처럼 한 개의 Material로 uv 정보만 바꿔서 텍스처링 하고싶었지만,
그러기엔 개발이 너무 지체될 것 같아서 이런 방식을 택했다 .....

또 Forward라는 속성을 추가해서 어디를 바라보는지의 정보. 즉, Block의 회전 정보도 지정할 수 있게 했다.

TODO: if문 사용하지 않기

Chunk.cs

    private void AddVoxelDataToChunk(Vector3Int pos, BlockType block)
    {
        if (block is NormalBlockType normalBlock)
        {
            for (int i = 0; i < 6; i++)
            {
                if (_world.CheckVoxel(pos + _data.faceChecks[i]))
                    continue;

                for (int j = 0; j < 4; j++)
                    _vertices.Add(pos + _data.voxelVerts[_data.voxelTris[i][j]]);

                AddTextureUV(normalBlock.GetTextureID(i));
                _triangles.Add(_vertexIdx);
                _triangles.Add(_vertexIdx + 1);
                _triangles.Add(_vertexIdx + 2);
                _triangles.Add(_vertexIdx + 2);
                _triangles.Add(_vertexIdx + 1);
                _triangles.Add(_vertexIdx + 3);
                _vertexIdx += 4;
            }
        }
        else if (block is SlideBlockType slideBlock)
        {
            var obj = Managers.Resource.GetCache<GameObject>("Slide Block.prefab");
            obj = UnityEngine.Object.Instantiate(obj, pos, Quaternion.identity);
            var slide = obj.GetComponent<SlideBlock>();
            slide.Forward = slideBlock.Forward;
            slide.FrontMaterial = slideBlock.FrontMaterial;
            slide.SideMaterial = slideBlock.SideMaterial;
            slide.transform.SetParent(_chunkObject.transform);
        }
    }

현재 블록의 타입이 NormalBlock과 SlideBlock으로 나뉘게 됐는데, 청크가 블록을 생성하는 과정에서 if문으로 타입매칭을 하고 있다.

이 부분을 Switch문의 패턴매칭으로 바꾸던지, 가상 메서드를 이용하던지 해야겠다.

아마 가상 메서드가 더 객체지향적이지 않을까?


3. [해야할 것 정리]

  1. SlideBlock도 WorldNavMeshBuilder의 source에 수집되도록 해야함.
  2. 금요일까지 3개의 분단된 섬을 만들고, 분단된 섬은 강으로 구분
  3. 생성된 맵을 저장하고 불러올 방법 결정. 아마 JSON일듯 ?
  4. 맵을 만들 때 어떻게 생성할 것인지. 에디터를 만들 시간이 있을까 ? 그렇다고 하나하나 수작업으로 만 개가 넘는 블럭을 채울 순 없다. 이 방법의 결정도 필요
profile
game developer

0개의 댓글