[Unity][3D-Game] Tower Defense Game (10)

suhan0304·2023년 12월 14일
1
post-thumbnail

강의영상 (12)


개발

노드 스크립트 수정

현재 금액에 따라 건설 가능 여부를 판단하고 노드에 마우스를 위치시켰을떄 건설이 가능한지와 아닌지에 따라 색을 구별할 수 있도록 한다.

위 기능 구현을 위해서 BuildManager에서 가지고 있는 돈이 터렛 건설 비용보다 큰 지 확인하는 함수를 작성하여 Node에서 사용한다.

BuildManager.cs

public bool HasMoney { get { return PlayerStats.Money >= turretToBuild.cost; } } // 터렛 비용보다 소지한 돈이 많은지 확인하는 함수

Node.cs

private void OnMouseEnter() //마우스가 오브젝트 충돌체에 지나가거나 들어갈 때
{
    if (EventSystem.current.IsPointerOverGameObject())
        return;

    if (!buildManager.CanBuild) //건설할 터렛이 null이 아니면 True 리턴됨 (BuildManager 참고)
        return;                                 

    //렌더러를 매번 마우스가 들어갈 때마다 아래와 같이 찾는 것은 성능 낭비 -> 게임 시작에서 한 번만 찾고 저장
    //GetComponent<Renderer>().material.color = hoverColor;

    //마우스를 올려놓았을 때 건물을 건설할 수 있는 충분한 돈이 있는지 확인후 노드 색을 변경
    if(buildManager.HasMoney) //돈이 충분하면 hoverColor
    {
        rend.material.color = hoverColor;
    }
    else //돈이 부족하면 notEnoughMoneyColor
    {
        rend.material.color = notEnoughMoneyColor;
    }
}

이제 돈이 부족할 때 변경할 노드의 색 재질 notEnoughMoneyColor을 인스펙터에서 초기화 해준다. ( public으로 선언해야 조절이 가능하다. )

위 사진처럼 노드 프리팹에서 NotEnoughMoneyColor 색을 지정해주면 아래와 같이 돈이 부족해서 건설을 할 수 없을 때는 붉은 색으로 노드가 변하는 것을 볼 수 있다.

GUI Font 설정

이제 카운트 다운과 소지한 돈을 출력하기 위한 GUI를 만들어 줄 것이다. 이를 위해 Font 설정을 해보자.

https://fonts.google.com/specimen/Roboto

위 홈페이지에서 제공하는 폰트를 사용하였다.

우측 상단의 Download family를 눌러 폰트 다운이 가능하다. 다운 받은 후 압축을 풀면 아래와 같이 ttf 파일들이 있다.

이 파일들을 유니티 프로젝트 창으로 드래그해서 임포트해주면 글꼴을 사용할 수 있다.

캔버스 설정

카운트 다운이 화면의 상단이 아니라 지도의 하단에 배치되도록 해보자. 먼저 기존의 WaveCountdownTimer을 비활성화 시킨 후에 작업을 진행한다.

캔버스를 새로 생성한 후 Render Mode를 World Space로 설정한다.

이제 크기와 각도를 잘 설정해서 지도의 하단 부분에 캔버스가 위치할 수 있도록 한다.

  • 이 때 X의 회전(Rotation)을 90으로 하면 캔버스가 눕혀지면서 지도와 같은 평면에 눕도록 할 수 있다.

위와 같이 지도의 하단 부분에 캔버스를 위치시키면 된다.

Money Text

이제 캔버스에 텍스트를 추가해 적절한 글자 크기와 색상, 폰트를 설정해준다.

  • 이름을 Money로 설정한다.
  • Font는 아까 다운 받은 Roboto-Thin을 사용한다.
  • Font Size = 150
  • Color는 흰색으로 설정한다.
  • Shadow 컴포넌트를 추가해준다.
  • 앵커를 전체 꽉차게 설정해준 다음에 정렬을 왼쪽 위로 한다.

위와 같이 설정을 마치면 다음과 같이 cost가 환경에 어울리게 잘 생성된 것을 확인할 수 있다.

Countdown Text

기존 Money를 복사해준 후 정렬을 오른쪽 상단으로 해준 후에 사용한다.

  • 이름을 Timer로 설정해준다.

설정을 마친 후 GameMaster의 Wave Spawner.cs의 Wave Countdown Text에 새로 만든 Timer(text)를 연결 시켜준다. ( Time Between Waves를 20으로 수정 )

이 때 카운트 다운의 출력 형식을 고정시켜주기 위해 아래와 같이 작성해준다.

WaveSpawner.cs

private void Update()
{
    if (countdown <= 0f) //카운트다운이 0 보다 작아지먄 Spawn Wave 실행
    {
        
        StartCoroutine(SpawnWave());
        countdown = timeBetweenWaves; //카운트 다운을 중간 시간으로 초기화
    }

    //deltaTime//마지막 프레임을 그린 후 경과한 시간
    countdown -= Time.deltaTime; //시간을 계속 줄인다.
        
    countdown = Mathf.Clamp(countdown, 0f, Mathf.Infinity); //카운트 다운이 0보다 낮아지지 않도록 설정

    waveCountdownText.text = string.Format("{0:00.00}", countdown); //출력 형식을 지정

    //waveCountdownText.text = Mathf.Round(countdown).ToString();
}

카운트 다운이 잘 작동하는 모습을 확인할 수 있다. 이제 돈도 업데이트 되도록 적용시켜보자.

MoneyUI.cs

돈도 카운트 다운과 같이 업데이트 될 수 있도록 MoneyUI 스크립트를 만들어 UI가 업데이트 되도록 로직을 구현한다.

현재 돈의 업데이트를 프레임마다 하도록 구현했지만 이는 프로젝트가 가볍기 때문에 괜찮지만 추후에 방대한 프로젝트를 관리할 때는 성능 낭비가 심하기 때문에 돈의 수치가 변화할 때마다 MoneyUI가 업데이트 되도록 로직을 구현하는 것이 좋다.
성능 여부를 잘 따져가면서 로직을 적절히 구현하는 것이 좋다.

using UnityEngine.UI;

public class MoneyUI : MonoBehaviour
{
    public Text moneyText;

    void Update()
    {
        moneyText.text = "$" + PlayerStats.Money.ToString();
    }
}

MoneyUI에 Money(Text)를 연결 시킨 후에 결과를 확인해본다.

Turret Cost

이제 Shop UI의 터렛의 아이콘에 비용도 같이 뜨도록 해보자. 기존 Shop UI의 Item 자식에 있는 Text를 삭제해 준후 Panel을 자식 오브젝트로 추가해준다.

  • 이름을 CostBP로 설정
  • 가시성 좋은 색으로 설정
  • 패널의 앵커를 가운데로 설정
    - 크기가 변하지 않도록 하기 위함

이제 이 Panel의 자식 오브젝트로 Text를 추가해준다.

  • 이름을 Cost로 설정
  • 글자 크기 32로 설정
  • Font를 Roboto - Right로 설정
  • 패널에 꽉 차도록 앵커 설정
  • 가로 세로 가운데 정렬

이제 수정 내용을 프리팹에 Apply All 시키고 미사일 터렛의 가격을 250 달러로 수정하면 아래와 같이 잘 적용된 것을 확인할 수 있다.

Build Effect

건물을 건설할 때 이펙트가 나오도록 하기 위해 파티클 이펙트를 이용해서 이펙트를 추가한다. 기존에 BulletImpactEffect 프리팹을 가져와서 수정해서 Build Effect를 만들어준다.

프리팹를 기반으로 다른 오브젝트를 만들기 위해선 프리팹을 가져와서 생성한 다음 프리팹을 끊고 작업해주는 것이 좋다.

  • 우클릭 > Prefab > Unpack Completely를 해준다.
  • 이름을 BuildEffect로 설정한다.
  • BuildEffect의 Particle System 컴포넌트를 복사하고 삭제해준 후 자식 오브젝트 Particles를 새로 만들어주고 해당 오브젝트의 컴포넌트로 옮겨준다.
  • Particle의 기타 설정은 강의 영상이나 깃허브 프로젝트를 직접 열어서 확인할 수 있다.

이제 파티클 설정이 끝났으면 해당 파티클 시스템에 적용 시킬 재질을 하나 새로 만들어준 후 적용한다.

Build Impact

이제 위에서 생성한 파티클 이펙트를 실행하도록 BuildManager 스크립트를 수정해준다. 건물을 건설할 때마다 해당 오브젝트를 건설 위치에 복사해서 생성해준 후 오브젝트 내부의 파티클 시스템을 Play 해준 다음에 다시 해당 오브젝트를 삭제하도록 로직을 구현한다.

public GameObject buildEffect; //건설 이펙트
    
GameObject effect = (GameObject)Instantiate(buildEffect, node.GetBuildPosition(), Quaternion.identity); // 이펙트 복사해서 생성해주기
Destroy(effect, 5f); // 생성하고 5초후에 이펙트 오브젝트 삭제

이제 인스펙터에서 BuildManager의 빌드 이펙트 오브젝트를 초기화 해준다.


결과물

profile
Be Honest, Be Harder, Be Stronger

0개의 댓글