Table of Contents
📹영상
영상에서 움직이고있는 트랜스폼 핸들이 플레이어 입니다.
플레이어의 이동에 맞춰 카메라에 빈 월드가 보이지 않게 블레이어 주변 9개의 맵을 재배치 합니다.
📌코드
InGameMapController.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.AddressableAssets;
using Cysharp.Threading.Tasks;
public class InGameMapController : MonoBehaviour
{
[SerializeField]
private AssetReferenceGameObject planePrefab;
[SerializeField]
private List<MapPlane> mapPlanes = new List<MapPlane>();
[SerializeField]
private Vector2 planeSize = new Vector2(65f, 47.5f);
private Vector2 playerCoords = Vector2.zero;
private void Start()
{
// 플레이어 주변 9개 맵 생성
RepositionMap();
}
private void Update()
{
CheckPlayerCoords();
}
private void CheckPlayerCoords()
{
// 현재 플레이어의 좌표
// (0, 0)가운데, (-1, 1)왼쪽 위, (1, -1)오른쪽 아래
Vector2 coord = playerCoords;
// 다른 plane으로 넘어가는 경계선 좌표
// (0, 0)일땐 곱하면 0되버리니까 더하기or빼기로 보정
var xMin = (coord.x * planeSize.x) - (planeSize.x / 2f);
var xMax = (coord.x * planeSize.x) + (planeSize.x / 2f);
var zMin = (coord.y * planeSize.y) - (planeSize.y / 2f);
var zMax = (coord.y * planeSize.y) + (planeSize.y / 2f);
Vector3 playerPos = InGameManager.Instance.Player.transform.position;
// 플레이어가 다른 plane으로 넘어갔는지 체크
// 넘어갔다면 플레어의 새 좌표를 만듦
if (playerPos.x < xMin)
coord.x -= 1;
else if(playerPos.x > xMax)
coord.x += 1;
if(playerPos.z < zMin)
coord.y -= 1;
else if(playerPos.z > zMax)
coord.y += 1;
// 플레이어가 다른 plane으로 넘어갔다면 맵을 재배치
if (playerCoords != coord)
{
playerCoords = coord;
RepositionMap();
}
}
private async UniTaskVoid RepositionMap()
{
// 플레이어 주위 좌표(인덱스는 중요하지 않음)
// 0, 1, 2
// 3, 4, 5
// 6, 7, 8
List<Vector2> around = new List<Vector2>()
{
Vector2.left + Vector2.up + playerCoords,
Vector2.up + playerCoords,
Vector2.right + Vector2.up + playerCoords,
Vector2.left + playerCoords,
Vector2.zero + playerCoords,
Vector2.right + playerCoords,
Vector2.left + Vector2.down + playerCoords,
Vector2.down + playerCoords,
Vector2.right + Vector2.down + playerCoords
};
// 플레이어 주위 9개 좌표에 없는(너무 멀어진) 맵들
List<MapPlane> repositionList = mapPlanes.Where(t => !around.Contains(t.coords)).ToList();
// 새로 들어온 플레이어 주변 좌표들
// 기존 좌표의 땅이 아직도 주변 좌표라면 그대로 두면 되니까 차집합으로 새 좌표만 구함
List<Vector2> newCoords = around.Except(mapPlanes.Select(x => x.coords)).ToList();
for (int i = 0; i < newCoords.Count; i++)
{
Vector2 coord = newCoords[i];
// 피봇이 plane모델의 센터니까 크기만큼 곱해서 위치를 구함
Vector3 pos = new Vector3(coord.x * planeSize.x, -1.25f, coord.y * planeSize.y);
// 너무 멀어진 맵들을 새로운 주변 위치로 재배치
if (repositionList.Count > i)
{
repositionList[i].coords = coord;
repositionList[i].transform.position = pos;
}
// Start에서 호출돼서 아직 plane오브젝트들이 없다면 어드레서블 프리팹으로 생성
else
{
var newPlane = await StaticManager.Instance.ResourceManager.InstantiateAsset<MapPlane>(planePrefab);
newPlane.coords = coord;
newPlane.transform.position = pos;
newPlane.transform.parent = transform;
mapPlanes.Add(newPlane);
}
}
}
}
MapPlane.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MapPlane : MonoBehaviour
{
public Vector2 coords;
}
📌인스펙터

Plane Prefab
: 맵 오브젝트 프리팹입니다 AssetReferenceGameObject
타입으로 어드레서블로 불러와 사용했습니다
Map Planes
: 생성된 맵들의 리스트입니다 미리 채워져있어도, 비어있어도 작동하도록 돼있습니다
Plane Size
: 맵 오브젝트의 3D 모델 사이즈 입니다 수동으로 입력합니다
'Unity > C#' 카테고리의 다른 글
[Unity] 플레이어를 따라오는 간단한 스프링 효과 (0) | 2025.01.15 |
---|---|
[Unity] Cinemachine으로 모바일 3인칭 카메라 만들기 (0) | 2024.07.04 |
[C#] 빠르게 C# 단일 스크립트를 슥 작성하고 쇽 실행하는 법 (polyglot notebooks) (0) | 2024.06.27 |
[Unity] JsonUtility.ToJson() 대신 Jobject.FromObject()를 쓰자 (1) | 2024.06.17 |
[Unity] Unity 3D Game Kit Lite템플릿 Damageable스크립트 분석 (1) | 2024.05.22 |