[Skill] 미니맵 제작하기



이전에 만들었던 SimpleCombat프로젝트를 사용한다.

미니맵 카메라

(1) 미니맵에 현재 화면 정보를 담기 위해 현재 화면을 위에서 내려다 보는 Top View 카메라 오브젝트를 생성해주고 이름을 MinimapCamera로 바꾼다.

(2) 카메라를 2D(Othographic)로 설정하기 때문에 y좌표는 맵보다 적당히 높게 설정(여기서는 10으로 설정)(회전 90, 0, 0)으로 설정

(3) MinimapCamera의 Camera컴포넌트 설정은 다음과 같다.

image

(4) 미니맵 카메라의 위치 제어를 위해 CopyPosition스크립트를 만든다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CopyPosition : MonoBehaviour
{
    [SerializeField]
    private bool x, y, z;       // 이 값이 true이면 target의 좌표, false이면 현재 좌표를 그대로 사용
    [SerializeField]
    private Transform target;       // 쫒아가야할 대상 Transform

    private void Update()
    {
        // 쫒아가야 할 대상이 없으면 종료
        if (target == null) return;

        transform.position = new Vector3(
            (x ? target.position.x : transform.position.x),
            (y ? target.position.y : transform.position.y),
            (z ? target.position.z : transform.position.z));
    }
}

(5) 미니맵 카메라 오브젝트에 CopyPosition스크립트를 추가한다.

image

위와 같이 타겟인 Player의 좌표를 x,z축 만 따라가게 만든다.

(6) Project 뷰에 렌더 텍스처를 하나 생성하고 이름을 Minimap Texture로 변경한다.

(7) MinimapTexture의 Filter Mode를 Point로 바꿔준다.

(8) MinimapCamera오브젝트의 Camera 컴포넌트에 있는 Target Texture에 MinimapTexture를 넣어준다.(이제 미니맵 카메라가 보는 것은 화면이 아닌 MinimapTextur에 출력 된다.)

(TIP) “Camera” 컴포넌트의 Target Texture가 null이면 카메라가 보는 화면을 모니터에 출력하고, Target Texture가 null이 아니면 카메라가 보는 화면을 Target Texture에 설정되어 있는 텍스처 파일에 저장한다.

미니맵 UI

(1) 미니맵 출력에 사용되는 UI를 관리하는 Panel을 하나 만들고 이름을 PanelMinimap으로 설정한다.

(2) 캔버스 오브젝트에 있는 캔버스 컴포넌트를 다음과 같이 설정한다.

image

(3) PanelMinimap의 세부사항을 설정한다.

(4) PanelMinimap의 자식오브젝트로 RawImage UI를 생성해준다.

(TIP) Image UI는 스프라이트 속성의 이미지만 설정 가능하기 때문에 RawImage UI를 이용해 다양한 속성(ex RenderTexture)의 이미지를 저장한다.

(5) RawImage 오브젝트의 설정을 다음과 같이 바꾼다.

image

(6) 현재 지역 정보를 출력하는 TextMeshPro를 하나 생성하고 이름을 TextMapName으로 설정한 후 PanelMinimap의 자식으로 배치한다. 그리고 텍스트 내용을 MapName으로 바꾼다.

(7) 미니맵을 줌 인 하는 버튼 UI를 생성하고 이름을 ButtonZoomIn으로 바꾼 뒤 PanelMinimap의 자식으로 배치한다. 그리고 위치와 텍스트를 수정한다.

(8) ButtonZoomIn을복사하고 이름을 ButtonZoomOut으로 바꾸고 위치와 텍스트를 수정한다.

image

(9) 미니맵 정보 제한을 위한 UIMinimap스크립트를 만든다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using TMPro;

public class UIMinimap : MonoBehaviour
{
    [SerializeField]
    private Camera minimapCamera;
    [SerializeField]
    private float zoomMin = 1;          // 카메라의 orthographicSize 최소 크기
    [SerializeField]
    private float zoomMax = 30;       // 카메라의 orthographicSize 최대 크기
    [SerializeField]
    private float zoomOneStep = 1;  // 1회 줌 할 때 증가/감소 되는 수치
    [SerializeField]
    private TextMeshProUGUI textMapName;

    private void Awake()
    {
        // 맵 이름을 현재 씬 이름으로 설정 (원하는 이름으로 설정)
        textMapName.text=SceneManager.GetActiveScene().name;
    }
    public void ZoomIn()
    {
        // 카메라의 orthographicSize 값을 감소 시켜 카메라에 보이는 사물 크기 확대 
        minimapCamera.orthographicSize=Mathf.Max(minimapCamera.orthographicSize-zoomOneStep, zoomMin);
    }
    public void ZoomOut()
    {
        // 카메라의 orthographicSize 값을 증가 시켜 카메라에 보이는 사물 크기 축소
        minimapCamera.orthographicSize = Mathf.Min(minimapCamera.orthographicSize + zoomOneStep, zoomMax);
    }
}

(10) Panelminimap오브젝트에 UIMinimap 스크립트를 추가한다.

(11) 줌인,줌아웃 버튼에 OnClick이벤트에 각각 ZoomIn(),ZoomOut()을 넣어준다.

(12) PlayerController스크립트를 수정해준다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [SerializeField]
    private Transform cameraTransform;
    private Movement3D movement3D;
    private PlayerAnimator playerAnimator;

    private void Awake()
    {
/*        //마우스 커서 안보이게 해준다
        Cursor.visible = false;
        //마우스 위치 고정
        Cursor.lockState = CursorLockMode.Locked;*/

        movement3D = GetComponent<Movement3D>();
        playerAnimator = GetComponentInChildren<PlayerAnimator>();
    }

    private void Update()
    {
        float hAxis = Input.GetAxis("Horizontal");
        float vAxis = Input.GetAxis("Vertical");

        playerAnimator.OnMovment(hAxis, vAxis);

        //이동속도 설정 (앞으로 이동할때만 5, 나머지 2)
        movement3D.MoveSpeed = vAxis > 0 ? 5.0f : 2.0f;
        //이동 함수 호출( 카메라가 보고 있는 방향을 기준으로 방향키에 따라 이동
        movement3D.MoveTo(cameraTransform.rotation * new Vector3(hAxis, 0, vAxis));

        //회전 설정 (항상 앞만 보도록 캐릭터의 회전은 카메라와 같은 회전 값으로 설정)
        transform.rotation=Quaternion.Euler(0,cameraTransform.eulerAngles.y,0);

        if (Input.GetKeyDown(KeyCode.Space))
        {
            movement3D.JumpTo();
            playerAnimator.OnJump();
        }

        // 마우스가 UI 위에 있을 때는 아래 코드를 실행하지 않도록 설정
        // UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject()값이 true:UI, false:UI 클릭 안됨
        if (UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject()) return;

        if (Input.GetMouseButtonDown(0))
        {
            playerAnimator.OnAttack();
        }
    }
}

UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject()를 사용하는 이유는 현재 프로젝트는 마우스 좌클릭을 하면 플레이어가 공격을 하는데 미니맵의 줌인,줌아웃 버튼을 클릭할 때 공격이 실행되지 않게 하려는 목적이다.

미니맵 커스터마이징

(1) 미니맵을 원하는 모양으로 보여지게 하기 위해 Image UI를 하나 생성하고 이름을 ImageMask로 설정한 후 PanelMinimap오브젝트의 자식으로 배치한다.

(2) ImageMask를 다음과 같이 설정한다.

image

(3) ImageMask오브젝트에 Mask컴포넌트를 추가한다.(ImageMask의 자식 이미지들이 ImageMask내부에만 보여지게 함)

(4) 미니맵 정보를 출력하는 RawImage를 ImageMask의 자식으로 넣어준다.

(5) 미니맵의 테두리 표현을 위한 Image UI를 만들고 이름을 ImageUI로 바꾸고 PanelMinimap오브젝트의 자식으로 배친한다.(현재 미니맵의 Mask와 동일한 모양을 사용하고,ImageMask 오브젝트보다 아래에 배치)

image

이렇게 하이어라키창에서 ImageRound가 Imagemask보다 아래 있는 이유는 ImageMask보다 앞에 있도록 하기 위함이다.

(6) PanelMinimap이 화면에 보이지 않도록 Image컴포넌트와 Canvas Renderer컴포넌트는 삭제해준다.

Minimap Culling Mask

현재 프로젝트는 3D로 설정되어 있어 2D오브젝트를 만들 수 없다. 그래서 Window - package Manager Vie에 가서 Unity Registry에 있는 2D Sprite 패키지 설치

(1) 2D->square오브젝트를 생성하고 이름을 MinimapIcon_Player로 바꾼다음 Player오브젝트의 자식으로 넣어준 다음 위치를 0, 2, 0 회전을 90, 0, 0으로 바꾸고 다운 받은 이미지를 넣어준다.

이제 여기서 중요하다. 현재 화면에 보이는 3차원의 플레이어는 미니맵에 보이지 않고 미니맵에 출력하기 위해 만든 플레이어 아이콘은 화면에 보이지 않아야 한다.

(2) Layer에 MinimapCamera, MainCamera 레이어를 추가해준다.

(3) MinimapIcon_Player의 레이어는 MinimapCamera로 설정하고, 화면에 출력되는 3D모델 Toko_sum은 레이어를 MainCamera로 설정해준다.

(4) MainCamera오브젝트의 Camera컴포넌트에서 Culling Mask변수에서 MinimapCamera레이어를 비활성화해서 레이어가 MinimapCamera인것을 MainCamera에서 보이지 않게 해준다.

(5) MinimapCamera오브젝트의 Camera컴포넌트에서 Culling Mask변수에서 MainCamera레이어를 비활성화해서 레이어가 MainCamera인것을 MinimapCamera에서 보이지 않게 해준다




© 2022. by KSC

Powered by sora