TIL 0215 게임개발 숙련 팀 과제 - 4 / 건축 기능 정리

강성원·2024년 2월 18일
0

TIL 오늘 배운 것

목록 보기
36/70

오늘은 팀 프로젝트를 급하게 마무리하느라 적을 것이 없어서 강의를 보며 익힌 건축 기능에 대해서 정리해보고자 한다.

모든 내용을 담기에는 내용이 조금 많기에 기능 구현에 접근하는 방법에 대해서만 써본다.

1. 건축물 미리보기

발헤임 같은 게임에서는 건축할 구조물을 선택하면 미리보기를 볼 수 있다.

1-1. 프리팹 준비

우선 실제 배치할 오브젝트와 미리보기로 보여줄 오브젝트가 필요하다.

두 오브젝트를 미리 프리팹으로 준비해준다.

// CraftMenu.cs
public class Craft
{
    public string craftName;
    public GameObject go_Prefab;
    public GameObject go_PreviewPrefab;
}

인스펙터 탭에서 해당 변수에 할당

1-2. Ray로 미리보기 오브젝트 배치

// CraftMenu.cs
private void PreviewPositionUpdate()
{
    if(Physics.Raycast(player.position, player.forward, out hitInfo ,range, layerMask))
    {
        go_Preview.SetActive(true);
        if (hitInfo.transform != null)
        {
            Vector3 point = hitInfo.point;
            go_Preview.transform.position = point;
        }
    }
    else
    { go_Preview.SetActive(false); }
}
  • Physics.Raycast메서드로 RaycastHit구조체의 변수 hitInfo에 레이가 닿는 곳의 위치를 할당한다.

  • player.position는 메인 카메라의 z축 방향이다. (1인칭 게임) => 바라 보는 방향으로 Ray를 쏜다.

  • go_Preview(미리보기 오브젝트)의 positionhitInfoposition을 할당

=> 레이가 도달한 곳에 미리보기 오브젝트를 위치시킴

1-3. 건축 제한

발헤임도 건축하고자 하는 곳에 다른 오브젝트가 있으면 빨간색으로 변하며 건축이 제한된다.

프로젝트에서는 미리보기 오브젝트와 부딪히는 다른 오브젝트들의 태그와 타입으로 건축가능 여부를 결정짓는다.

  • 미리보기 오브젝트에는 PreviewObject스크립트 컴포넌트를 붙여준다.

  • 스크립트에는 충돌체 리스트 List<Collider> colliderList가 있음

요점은 미리보기 오브젝트가 다른 오브젝트에 충돌시 충돌체 리스트에 요소를 추가하는 것이다.

//PreviewObject.cs
private void OnTriggerEnter(Collider other)
{
    if(other.transform.tag == "Structure") // 부딪힌 물체의 태그가 Structure
    {
        if (other.GetComponent<Building>().type != needType) // Building 컴포넌트의 type이 
            colliderList.Add(other);
        else
            needTypeFlag = true;

    }
    else
    {
        if (other.gameObject.layer != layerGround && other.gameObject.layer != IGNORE_RAYCAST_LAYER)
        {
            colliderList.Add(other);
        }
    }
}

미리보기 오브젝트와 충돌한 오브젝트의 태그와 타입의 조건을 따져서 붙으면 안되는 오브젝트라면 충돌체 리스트인 colliderList에 충돌한 오브젝트의 충돌체를 추가한다.

//PreviewObject.cs
public bool IsBuildable()
{
    if(needType == Building.Type.Normal)
        return colliderList.Count == 0;
    else
        return colliderList.Count == 0 && needTypeFlag;
}

그리고 충돌체 리스트에 뭐라도 하나 들어가 있으면 건축을 제한하도록 한다.

2. 건축물 배치

건축물 배치는 별것 없다.

현재 미리보기 오브젝트의 위치에 배치할 오브젝트를 생성해주면 끝이다.

public void Build()
{
    if(isPreviewActivated && go_Preview.GetComponent<PreviewObject>().IsBuildable())
    {
    	//오브젝트 프리팹의 객체화
        Instantiate(go_Prefab, go_Preview.transform.position, go_Preview.transform.rotation);
        //기존의 미리보기 오브젝트는 소멸시킨다.
        Destroy(go_Preview);

        isActivated = false;
        isPreviewActivated = false;
        go_Preview = null;
        go_Prefab = null;
    }
}
profile
개발은삼순이발

0개의 댓글