[Unity] Project. Personal_3

Lingtea_luv·2025년 5월 30일

Project

목록 보기
19/38
post-thumbnail

Where Am I?


오늘 구현한 것은 크게 미니맵과 인벤토리 및 상자 보관, 제작 시스템, 오브젝트 랜덤 생성 로직이다. 슬슬 기능 구현은 다되어가지만, 미니맵 구현에서 예상보다 시간이 소요되어 예정이 조금 밀리게됐다.

이번 포스트에서는 구현한 미니맵 로직을 분석하고 소개하려한다. 간단히 맵과 연동되어 플레이어의 탐색에 따라 밝혀지는 POE의 맵핑과 같은 시스템을 구현했다.

MinimapData

실제 생성되는 맵과 연동시키기 위해 맵의 데이터를 바탕으로 미니맵 데이터를 저장한다.

public class MinimapData : MonoBehaviour
{
    [Header("Drag&Drop")] 
    [SerializeField] private MapData _mapData;
    
    private int _mapSize;
    public int MapSize => _mapSize;
    
    private int[,] _map;
    public int[,] Map => _map;

    private int _offset;

    private void Start()
    {
        Init();
        Initialize();
    }

    private void Initialize()
    {
        // 미니맵 생성
        _map = new int[_mapSize, _mapSize];
        
        // 맵 크기 보정
        for (int x = 0; x < _mapSize; x++)
        {
            for (int y = 0; y < _mapSize; y++)
            {
                _map[x, y] = _mapData.Map[x * _offset, y * _offset];
            }
        }
    }

    private void Init()
    {
        _mapSize = _mapData.MapSize;
        _offset = _mapData.Offset;
    }
}

MinimapCam

public class MinimapCam : MonoBehaviour
{
    [Header("Drag&Drop")] 
    [SerializeField] private Transform _player;

    [Header("InputNumber")] 
    [SerializeField] private float _zoomSpeed;
    [SerializeField] private float _minY;
    [SerializeField] private float _maxY;

    private void LateUpdate()
    {
        transform.position = new Vector3(_player.position.x / 5, transform.position.y, _player.position.z / 5);
        if (!ItemManager.Instance.HasCompass)
        {
            transform.rotation = Quaternion.Euler(90,_player.rotation.eulerAngles.y,0);
        }

        float scroll = Input.GetAxis("Mouse ScrollWheel");
        transform.position += Vector3.up * (scroll * _zoomSpeed);

        float clampY = Mathf.Clamp(transform.position.y, _minY, _maxY);
        transform.position = new Vector3(transform.position.x, clampY, transform.position.z);
    }
}

Minimap

public class Minimap : MonoBehaviour
{
    [Header("Drag&Drop")]
    [SerializeField] private Transform _player;
    [SerializeField] private GameObject _playerPrefab;

    private GameObject _playerObject;
    private bool _isTurnOn;
    private Camera _minicam;
    
    private void Awake()
    {
        Init();
    }

    private void Start()
    {
        Vector3 startPos = new Vector3(_player.position.x / 5, -1, _player.position.z / 5);
        _playerObject = Instantiate(_playerPrefab, startPos, Quaternion.identity);
    }
    
    private void Update()
    {
        _playerObject.transform.position = new Vector3(_player.position.x / 5, -1, _player.position.z / 5);
        if (Input.GetKeyDown(KeyCode.Tab))
        {
            _isTurnOn = !_isTurnOn;
            if (_isTurnOn != _minicam.gameObject.activeSelf)
            {
                _minicam.gameObject.SetActive(_isTurnOn);
            }
        }
    }

    private void Init()
    {
        _minicam = GetComponentInChildren<Camera>();

        _minicam.rect = new Rect(0.35f, 0.35f, 0.3f, 0.3f);
        
        _isTurnOn = false;
        _minicam.gameObject.SetActive(_isTurnOn);
    }
}

MinimapGenerator

public class MinimapGenerator : MonoBehaviour
{
    [Header("Drag&Drop")]
    [SerializeField] private MinimapData _data;
    [SerializeField] private GameObject _wallPrefab;
    [SerializeField] private GameObject _tilePrefab;
    
    private int[,] _map;
    private int _mapSize;

    private void Start()
    {
        Init();
        GenerateMap();
    }

    private void GenerateMap()
    {
        for (int z = 0; z < _mapSize; z++)
        {
            for (int x = 0; x < _mapSize; x++)
            {
                Vector3 pos = new Vector3(x, -1, z);
                if (_map[z, x] == 1)
                {
                    Instantiate(_wallPrefab, pos, Quaternion.identity,transform);
                }
                else
                {
                    Instantiate(_tilePrefab, pos, Quaternion.identity,transform);
                }
            }
        }
    }

    private void Init()
    {
        _map = _data.Map;
        _mapSize = _data.MapSize;
    }
}

MinimapReveal

public class MinimapReveal : MonoBehaviour
{
    [Header("Drag&Drop")] 
    [SerializeField] private Transform _player;

    [Header("InputNumber")] 
    [SerializeField] private float _revealRange;
        
    private List<GameObject> _tiles;
    
    private void Start()
    {
        Init();
    }

    private void Update()
    {
        foreach (var tile in _tiles)
        {
            Vector3 targetPos = new Vector3(_player.position.x / 5, -1, _player.position.z / 5);
            if (Vector3.Distance(tile.transform.position, targetPos) < _revealRange)
            {
                tile.SetActive(true);
            }
        }
    }

    private void Init()
    {
        _tiles = new List<GameObject>();
        foreach (var tile in GetComponentsInChildren<MeshFilter>())
        {
            tile.gameObject.SetActive(false);
            _tiles.Add(tile.gameObject);
        }
    }
}
profile
뚠뚠뚠뚠

0개의 댓글