[개발일지] 28. 맵 이동 & 생성

2025. 1. 25. 21:37·유니티 프로젝트/점토게임
목차
  1. 0. 들어가기 전에
  2. 1. 프리팹
  3. 2. 게임 오브젝트
  4. 3. 스크립트
  5. 3.1 MapSpawner 스크립트
  6. 3.2 MapSpawner 스크립트 설명
  7. 3.3 MapLoop 스크립트
  8. 3.4 MapLoop 스크립트 설명
  9. 4. 결과물

0. 들어가기 전에

이번엔 프리팹으로 만든 맵을 일정 시간마다 게임에 생성하도록 했다. 그리고 기존에 만들어놨던 ScrollingBackground 스크립트를 부착해서 맵이 이동하도록 했다.

 

 


 

 

1. 프리팹

일단 맵 프리팹을 4개 만들어놨다. 지금은 원하는 기능을 구현하기 위해 맵을 대충 만들었는데 다음에 맵 종류도 더 늘릴 것이다. 일단 Grid 에 4개의 프리팹을 놓으면 아래 사진처럼 보인다.

 

맵에 장애물과, 몬스터가 있는 경우가 있는데 이는 맵의 자식으로 넣어놓은 것이다. 

더보기

1. 인스펙터 창

맵의 인스펙터 창의 상태는 다음 사진과 같다. Scrolling Background 스크립트를 부착해서 맵이 이동할 수 있도록 했다.

 

 


 

 

2. 게임 오브젝트

이번에 새로 만든 게임 오브젝트는 MapSpawner 이다. Grid 의 자식으로 넣어놨다.

 

더보기

1. 인스펙터 창

맵 스포너의 Transform 을 보면 위치가 (7, 0, 0) 인 걸 확인 할 수 있다. 맵을 생성하면 MapSpawner 에 자식으로 들어가는데 자식은 저절로 MapSpawner 의 위치를 반영해서 게임 화면 속에 위치한다.

 

Map 이 생성될 때마다 시작 지점을 직접 설정해주기 보다는 MapSpawner 에 자식으로 들어가도록 하는게 훨씬 편해서 이렇게 했다.

 

MapSpawner 는 스크립트로 MapSpawner 를 가지는데 맵 프리팹 변수로 이번에 만든 맵 프리팹들을 넣었다. 이제 이 프리팹으로 pool 을 만들어서 사용한다.

 

 


 

 

3. 스크립트

이번에 새로 만든 스크립트는 MapSpawner 와 MapLoop 이다.

 

3.1 MapSpawner 스크립트

using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Unity.VisualScripting;
using UnityEngine;

public class MapSpawner : MonoBehaviour
{
    [Header("Map Contoller")]
    public GameObject[] mapPrefabs;
    public List<GameObject>[] pool;

    public float curTime = 0;
    public float targetTime = 0.5f; // targetTime 마다 맵 생성
    public int mapCount;

    private Coroutine mapCoroutine;

    private void Awake()
    {
        mapCount = mapPrefabs.Length; // 프리팹 개수

        pool = new List<GameObject>[mapCount]; // 배열 만들기
        for (int i=0; i<mapCount; i++)
        {
            pool[i] = new List<GameObject>(); // 리스트 새로 만들기
        }
    }

    private void Start()
    {
        mapCoroutine = StartCoroutine(SpawnMap()); // 맵 생성 코루틴 시작   
    }


    private IEnumerator SpawnMap()
    {
        while (true)
        {
            int mapIdx = Random.Range(0, mapCount);
            GameObject select = null;

            foreach (GameObject map in pool[mapIdx])
            {
                // 만약 놀고 있는 맵 게임 오브젝트를 발견하면 그거 활성화
                if (map.activeSelf == false)
                {
                    select = map;
                    map.SetActive(true); // 맵 활성화
                    break;
                }
            }

            // 발견 못 하면 새로 생성
            if (select == null)
            {
                select = Instantiate(mapPrefabs[mapIdx], transform);
                pool[mapIdx].Add(select); // 새로 생성한 게임 오브젝트를 풀에 넣기
            }

            yield return new WaitForSeconds(targetTime); // targetTime 만큼 기다리기
        }
    }
}

 

3.2 MapSpawner 스크립트 설명

더보기

1. 변수

선언한 변수는 다음과 같다.

 

미리 만들어놓은 맵 프리팹을 저장하기 위한 mapPrefabs 변수와 생성된 맵을 관리하기 위한 pool 변수를 선언했다.

 

맵을 일정 시간마다 생성하기 위해서 curTime, targetTime 변수를 선언했다. 맵을 생성하는 로직을 코루틴으로 만들었는데 코루틴을 시작하고 이를 저장해놓기 위해 mapCoroutine 변수를 선언했다.

[Header("Map Contoller")]
public GameObject[] mapPrefabs;
public List<GameObject>[] pool;

public float curTime = 0;
public float targetTime = 0.5f; // targetTime 마다 맵 생성
public int mapCount;

private Coroutine mapCoroutine;

 

 

2. Awake()

mapCount 에 현재 프리팹의 개수를 넣는다. 이 값으로 배열의 크기를 설정했다. List 에 요소를 넣기 위해서는 무조건 List 가 만들어져 있어야 하기 때문에 반복문을 돌면서 하나하나 만들어줬다.

private void Awake()
{
    mapCount = mapPrefabs.Length; // 프리팹 개수

    pool = new List<GameObject>[mapCount]; // 배열 만들기
    for (int i=0; i<mapCount; i++)
    {
        pool[i] = new List<GameObject>(); // 리스트 새로 만들기
    }
}

 

 

3. Start()

맵 생성 코루틴을 시작하고 변수에 저장했다. 나중에 코루틴을 직접 종료시킬 때 이용하기 위함이다.

private void Start()
{
    mapCoroutine = StartCoroutine(SpawnMap()); // 맵 생성 코루틴 시작   
}

 

 

4. SpawnMap()

맵 생성 코루틴이다. 랜덤으로 받은 값으로 해당 맵을 생성하도록 했다.

 

풀을 돌면서 놀고 있는 맵이 있으면 활성화시키도록 했고, 없다면 해당 맵을 새로 생성하도록 했다. 새로 생성한 맵은 pool 에 Add 해서 추가했다.

 

targetTime 동안 기다리도록 해서 맵이 일정 시간마다 생성되도록 했다.

private IEnumerator SpawnMap()
{
    while (true)
    {
        int mapIdx = Random.Range(0, mapCount);
        GameObject select = null;

        foreach (GameObject map in pool[mapIdx])
        {
            // 만약 놀고 있는 맵 게임 오브젝트를 발견하면 그거 활성화
            if (map.activeSelf == false)
            {
                select = map;
                map.SetActive(true); // 맵 활성화
                break;
            }
        }

        // 발견 못 하면 새로 생성
        if (select == null)
        {
            select = Instantiate(mapPrefabs[mapIdx], transform);
            pool[mapIdx].Add(select); // 새로 생성한 게임 오브젝트를 풀에 넣기
        }

        yield return new WaitForSeconds(targetTime); // targetTime 만큼 기다리기
    }
}

 

3.3 MapLoop 스크립트

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Tilemaps;

public class MapController : MonoBehaviour
{
    [Header("Map Info")]
    public float curTime = 0;
    public float targetTime = 2f; // 활성화된지 2초가 지나면 활성화 끄기

    private void OnEnable()
    {
        // 활성화 되면 자동으로 호출됨
        ResetMap();
    }

    private void Update()
    {
        curTime += Time.deltaTime;

        if (curTime >= targetTime)
            gameObject.SetActive(false); // 비활성화!
    }

    public void ResetMap()
    {
        curTime = 0;
        transform.position = Vector3.zero; // (0, 0, 0) 로 위치 설정
    }
}

 

3.4 MapLoop 스크립트 설명

더보기

1. 변수

선언한 변수는 다음과 같다. 생성된 맵이 카메라를 벗어났는데도 계속해서 활성화 된 상태로 있으면 안 되기 때문에 일정 시간이 지나면 비활성화 하도록 했다.

 

targetTime 변수를 만들어 놓고 이 시간이 지나면 자기 자신을 비활성화 하도록 했다.

[Header("Map Info")]
public float curTime = 0;
public float targetTime = 2f; // 활성화된지 2초가 지나면 활성화 끄기

 

 

2. OnEnable()

맵이 활성화 될 때 자동으로 호출되는 메서드이다. 활성화 될 때 맵의 상태를 초기화할 수 있도록 ResetMap 메서드를 호출했다.

private void OnEnable()
{
    // 활성화 되면 자동으로 호출됨
    ResetMap();
}

 

 

3. Update()

curTime 이 targetTime 보다 크거나 같아지면 스스로를 비활성화 하도록 했다.

private void Update()
{
    curTime += Time.deltaTime;

    if (curTime >= targetTime)
        gameObject.SetActive(false); // 비활성화!
}

 

 

4. ResetMap()

맵의 상태를 초기화 하는 메서드이다. 

public void ResetMap()
{
    curTime = 0;
    transform.position = Vector3.zero; // (0, 0, 0) 로 위치 설정
}

 

 


 

 

4. 결과물

 

맵이 일정 시간마다 생성되는 것을 확인할 수 있다. 그리고 이제 맵이 이동한다.

 

  1. 0. 들어가기 전에
  2. 1. 프리팹
  3. 2. 게임 오브젝트
  4. 3. 스크립트
  5. 3.1 MapSpawner 스크립트
  6. 3.2 MapSpawner 스크립트 설명
  7. 3.3 MapLoop 스크립트
  8. 3.4 MapLoop 스크립트 설명
  9. 4. 결과물
'유니티 프로젝트/점토게임' 카테고리의 다른 글
  • [개발일지] 30. 야생 난이도에 따른 맵 생성 & 배경 설정
  • [개발일지] 29. 맵 프리팹 수정 & 스크립트 수정
  • [개발일지] 27. 플레이어 & 장애물 상호작용
  • [개발일지] 26. 몬스터 기초 제작
dubu0721
dubu0721
dubu0721 님의 블로그 입니다.
dubu0721 님의 블로그dubu0721 님의 블로그 입니다.
  • dubu0721
    dubu0721 님의 블로그
    dubu0721
  • 전체
    오늘
    어제
    • 분류 전체보기 (343) N
      • 프로그래밍언어론 정리 (5)
      • 컴퓨터네트워크 정리 (5)
      • 알고리즘&자료구조 공부 (64)
        • it 취업을 위한 알고리즘 문제풀이 입문 강의 (60)
        • 학교 알고리즘 수업 (3)
        • 실전프로젝트I (0)
      • 백준 문제 (196) N
        • 이분탐색 (7)
        • 투포인트 (10)
        • 그래프 (7)
        • 그리디 (24)
        • DP (25)
        • BFS (18) N
        • MST (7)
        • KMP (4)
        • Dijkstra (3)
        • Disjoints Set (4)
        • Bellman-Ford (2)
        • 시뮬레이션 (3)
        • 백트래킹 (15)
        • 위상정렬 (5)
        • 자료구조 (25)
        • 기하학 (1)
        • 정렬 (11)
        • 구현 (8)
        • 재귀 (8)
        • 수학 (8)
      • 유니티 공부 (11)
        • 레트로의 유니티 게임 프로그래밍 에센스 (11)
        • 유니티 스터디 자료 (0)
        • C# 공부 (0)
      • 유니티 프로젝트 (48)
        • 케이크게임 (13)
        • 점토게임 (35)
      • 언리얼 공부 (10)
        • 이득우의 언리얼 프로그래밍 (10)
      • 진로 (1)
      • 논문 읽기 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    재귀
    큐
    수학
    스택
    골드메탈
    dp
    레트로의 유니티 프로그래밍
    이벤트 트리거
    자료구조
    이득우
    BFS
    시뮬레이션
    유니티
    백트래킹
    투포인터
    백준
    우선순위큐
    유니티 공부 정리
    C#
    오블완
    정렬
    티스토리챌린지
    이분탐색
    그리디
    해시
    바킹독
    맵
    언리얼
    유니티 프로젝트
    그래프
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
dubu0721
[개발일지] 28. 맵 이동 & 생성

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.