오늘은 건축 시스템에 가구 설치를 추가!

직접 만든 가구들
만드는건 생각보다 재미있어서 블랜더까지 손 벌려 모델링을 해보고 싶었지만
개발자로서 필요한 영역은 아니라고 튜터님에게 조언 받아서 깔끔하게 포기

건축에 들어갈 물건들은 간단하게 구현만 하자

그리고 가구 배치를 따로 메서드로 구현해서 실험 결과 다행이 커넥터의 스냅효과를 받지 않고 바닥에 잘 설치 되었는데...

문제 발생

설치할 가구가 커넥터 위에 설치가 가능한것
다른 게임들의 건축 시스템을 보면 토대가 되는 바닥이랑 벽은 챱 달라붙게 되고 세부적인 가구들은 자유롭게 설치 가능하게끔 되어있는데
커넥터가 있을만한 부분을 선택해도 딱히 걸리는게 없었는데....

문제는 바로 파악했고 어떻게 고칠까 고민하다가
커넥터에 tag를 추가해서 ray를 사용했을 때 무시하게끔 해결

 // 가구 배치
        if (currentBuildType == SelectedBuildType.Furniture)
        {
            GhostFurnitureBuild();
            return;
        }

타입에 가구를 추가함으로 서 타입이 가구일땐 커넥터의 collider 상관없이 설치 가능하게끔 되어있고

 Collider[] colliders = Physics.OverlapSphere(ghostBuildGameObject.transform.position, connectorOverlapRadious, connectorLayer);
 if (colliders.Length > 0)
 {
     // 연결 가능한 오브젝트 존재 시 연결 시도
     GhostConnectBuild(colliders);
 }
 else
 {
     // 연결 불가(분리된) 상태 처리
     GhostSeperateBuild();

     if (isGhostInValidPosition)
     {
         Collider[] overlapColliders = Physics.OverlapBox(ghostBuildGameObject.transform.position, new Vector3(2f, 2f, 2f), ghostBuildGameObject.transform.rotation);
         foreach (Collider overlapCollider in overlapColliders)
         {
             if (overlapCollider.gameObject != ghostBuildGameObject && overlapCollider.transform.root.CompareTag("Buildables"))
             {
                 GhostifyModel(modelParent, ghostMaterialInvalid);
                 isGhostInValidPosition = false;
                 return;
             }
         }
     }
 }

가구가 아닌 건축물들은 콜라이더를 가져와서 연결이 가능한지 확인하고 아니면 빨간색 프리뷰를 보여줌
근데 프리뷰도 초록색으로 설치 가능하다고 알려주는 프리뷰가 있고 빨간색으로 설치 불가를 알려주는 프리뷰가 있어서 두개다 정의 해야하더라...
하면서 점점 보이는게 많아지는데 아는만큼 보인다고 다른 게임들 즐겼을 때 이런 느낌하고 비슷하게 만들어졌을거 생각하면.... 존경합니다....

InValidPosition이 InvalidPosition 하고 차이가 없지않나? 라고 미래의 내가 생각할 지도 모르니깐
In Valid Position 알맞는 위치에 속해있는가
Invalid Position 부적절한 위치에 속해있는가

컨벤션을... 지키자...

private void GhostFurnitureBuild()
{
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    RaycastHit[] hits = Physics.RaycastAll(ray);

    RaycastHit? targetHit = null;
    float minDistance = float.MaxValue;

    foreach (RaycastHit h in hits)
    {
        // Connector는 무시!
        if (h.collider.CompareTag("Connector"))
            continue;

        // 나머지 바닥, Floor, Ground 등만 설치 대상으로 사용
        if (h.distance < minDistance)
        {
            minDistance = h.distance;
            targetHit = h;
        }
    }

    if (targetHit.HasValue)
    {
        ghostBuildGameObject.transform.position = targetHit.Value.point;

        if (Vector3.Angle(targetHit.Value.normal, Vector3.up) < maxGroundAngle)
        {
            GhostifyModel(modelParent, ghostMaterialValid);
            isGhostInValidPosition = true;
        }
        else
        {
            GhostifyModel(modelParent, ghostMaterialInvalid);
            isGhostInValidPosition = false;
        }
    }
    else
    {
        GhostifyModel(modelParent, ghostMaterialInvalid);
        isGhostInValidPosition = false;
    }
}

바닥이랑 벽 설치는 Collider 를 가져와서 붙이게끔 설정 되어있으니 따로 가구 전용 설치 메서드
RaycastAll를 사용해서 모든 정보를 가져오게끔 한 다음 CompareTag 로 Connector는 무시하고 가장 가까운 지점에 설치할 수 있도록 설정

내일 주석을 달며 공부를 이어나가자
UI 계획 원통으로 나와서 원하는 설계도?를 선택하면 건축될 수 있도록 변경해보자

다른 게임에서 사용되는 UI 가져와보면 될것 같은데...

0개의 댓글