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

suhan0304·2023년 11월 28일
0
post-thumbnail

강의영상 (6)


개발

호버 이벤트

노드에 건물을 짓는 로직을 작성하기 위해 Node 프리팹에 Node 스크립트를 추가해주자. 노드에 추가될 로직은 아래와 같다.

  1. 마우스를 위에 올리면 하이라이트 표시됨
  2. 건물을 선택하고 노드위에 클릭할 시 건물이 지어져야함

1번 로직을 먼저 구현하고 2번은 건물을 짓기 전에 시각적 피드백이 와서 누르는 동작이 잘 작동하고 있는지를 먼저 확인해본다.

Node.cs

using UnityEngine;

public class Node : MonoBehaviour
{
    public Color hoverColor; //색

    private Renderer rend;
    private Color startColor;

    private void Start()
    {
        rend = GetComponent<Renderer>();//게임이 시작될 때 렌더러를 미리 저장
        startColor = rend.material.color; //시작 색을 저장 후 기억
    }

    private void OnMouseEnter() //마우스가 오브젝트 충돌체에 지나가거나 들어갈 때
    {
        //렌더러를 매번 마우스가 들어갈 때마다 아래와 같이 찾는 것은 성능 낭비 -> 게임 시작에서 한 번만 찾고 저장
        //GetComponent<Renderer>().material.color = hoverColor;

        //Start에서 저장된 렌더러를 호출해서 색을 변경
        rend.material.color = hoverColor;
    }

    private void OnMouseExit() //마우스가 오브젝트에서 나갈 때
    {
        rend.material.color = startColor; //startColor로 되돌리기
    }
}

OnMouseEnter : 마우스가 오브젝트를 지나가거나 들어갈 때 호출되는 유니티 제공 함수
OnMouseExit : 마우스가 오브젝트를 다시 나갈 때 호출되는 유니티 제공 함수

위처럼 마우스가 들어올 때 나갈 때 색이 변경되도록 하여 하이라이트 처리한다.

터렛 건설

이제 노드를 클릭할 시 터렛이 건설되도록 로직을 구현해보자. 클릭 이벤트는 OnMouseDown으로 구현할 수 있다.

private void OnMouseDown()
{
    if(turret != null) //터렛 오브젝트가 null이 아니면 이미 터렛이 있다는 모습
    {
        Debug.Log("Can't build there! - TODO : Display on screen.");
        return;
    }

    //Build a turret
}

건물을 짓는 것은 GameMaster 오브젝트에 Build Manager를 통해 진행하도록 한다.

UI를 통해 건물을 선택하고 해당 건물을 건설하고, 필요한 돈을 지불하고 등, 등 건설에 관련된 작업을 처리하는 스크립트가 Node 스크립트에 들어가는 것은 굉장히 비효율 적이므로 Build Manager 스크립트에서 건설을 관리하도록 구현한다.

모든 노드에서 참조를 통해 빌드 매니저를 가져오는 것은 굉장히 비효율 적이므로 싱글톤 패턴을 사용해 노드들이 참조 없이 빌드 매니저를 불러올 수 있도록 구현한다.

Build Manager

using UnityEngine;

public class BuildManager : MonoBehaviour
{
    public static BuildManager instance; //싱글톤 패턴으로 빌드 매니저를 선언

    private void Awake()
    {
        if (instance != null)  //선언된 적 있으면 더 이상 선언 X
        {
            // 이미 빌드 매니저 인스턴스가 존재
            Debug.LogError("More than one BuildManager in scene!");
            return;
        }
        //게임이 시작하면 새로운 빌드 매니저를 instance에 저장.
        //빌드 매니저는 하나의 인스턴스로만 유지됨 (싱글톤 패턴의 특징 : 하나의 인스턴스만 유지)
        instance = this;
    }

    public GameObject standardTurretPrefab; //기본 터렛 프리팹

    private void Start()
    {
        turretToBuild = standardTurretPrefab; // 시작한 후의 건설은 일단 기본 터렛이 건설되도록 초기화
    }

    private GameObject turretToBuild; //노드 선택 시 건설할 터렛

    public GameObject GetTurretToBuild() //건설할 터렛을 가져오는 함수
    {
        return turretToBuild;
    }
}

이제 터렛 건설부분을 구현해서 클릭시에 빌드 매니저로부터 건설할 터렛을 불러와 해당 터렛을 건설한다.

Node.cs

private void OnMouseDown()
{
    if(turret != null) //터렛 오브젝트가 null이 아니면 이미 터렛이 있다는 모습
    {
        Debug.Log("Can't build there! - TODO : Display on screen.");
        return;
    }

    //Build a turret
    GameObject turretBuild = BuildManager.instance.GetTurretToBuild(); //빌드 매니저를 바로 호출 가능(싱그톤)
        
    //노드 위치에 건설 시 노드와 동일한 Position에 겹쳐서 생성됨 ( 노드 내부에 터렛이 위치함 )
    //높이 오프셋을 선언해 준 후 위치 벡터에 더해서 초기 생성 위치를 조정해준다. -> Offset은 노드 프리팹의 인스펙터에서 조정 가능 
    turret =  (GameObject)Instantiate(turretBuild, transform.position + positionOffset, transform.rotation); //건설할 터렛을 복사 한 후 turret 변수에 초기화
}

이제 건물이 정상적으로 건설되는지 플레이를 눌러 확인해보자.


결과물

profile
Be Honest, Be Harder, Be Stronger

0개의 댓글