2D RPG – 7. 카메라 영역 설정
현재는 카메라가 기본적으로 설정한 부분으로 이동하고 있습니다.
가끔 캐릭터 이동시에 카메라가 맵영역을 벗어날 때가 있습니다.
이때 카메라가 현재 맵을 벗어나지 않도록 처리해야 합니다.
1.맵 이동 수정
카메라 영역 설정 이전에 몇가지 이동 기능을 바꿔줍니다.
맵내에 도로 영역의 상단과 하단의 이동하는 공간을 만들고, 상단으로 이동시 Scene 이동, 하단으로 이동시 Map 이동이 일어나도록 처리합니다.
스크립트 파일도 따로 제작하여 처리합니다.
TransferScene.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class TransferScene : MonoBehaviour
{
public string transferMapName; //이동할 맵이름
private MovingObject thePlayer;
// Start is called before the first frame update
void Start()
{
thePlayer = FindObjectOfType<MovingObject>();
}
// 박스 콜라이더에 닿는 순간 이벤트 발생
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.name == "Player")
{
thePlayer.currentMapName = transferMapName;
SceneManager.LoadScene(transferMapName);
}
}
}
Scene 이동은 이전과 크게 다른점은 없습니다.
TransferMap.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class TransferMap : MonoBehaviour
{
public string transferMapName; //이동할 맵이름
public Transform target; // 이동할 타겟 설정
public BoxCollider2D targetBound;
private MovingObject thePlayer;
private CamaraManager theCamera;
// Start is called before the first frame update
void Start()
{
thePlayer = FindObjectOfType<MovingObject>();
theCamera = FindObjectOfType<CamaraManager>();
}
// 박스 콜라이더에 닿는 순간 이벤트 발생
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.name == "Player")
{
thePlayer.currentMapName = transferMapName;
//SceneManager.LoadScene(transferMapName);
theCamera.SetBound(targetBound);
theCamera.transform.position = new Vector3(target.transform.position.x, target.transform.position.y, theCamera.transform.position.z);
thePlayer.transform.position = target.transform.position;
}
}
}
Man 이동시키는 구역에 닿게 되면 카메라가 이동함과 동시에 카메라 스크립트 파일내에 있는 SetBound 함수가 실행됩니다.
이 함수는 Map 이동의 경우 Map1,Map2로 나누어져 있으므로, 카메라 이동을 방지해둔 기능과 충돌이 발생하게 됩니다. 따라서 Map 이동이 발생할때 Map1에 설정되어 있는 카메라 영역이 Map2의 설정으로 이동되는 함수가 필요하게 됩니다.
2.카메라 스크립트 수정
카메라 스크립트를 수정하기전에 Map1, Map2내에 빈 객체를 만들고 크기를 맵크기와 비슷하게 맞춰줍니다.
이름은 A bound, B bound로 선언합니다.
[Is trigger] 옵션을 체크하여 기존 캐릭터 객체와 충돌하지 않도록 해줍니다.
CameraManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CamaraManager : MonoBehaviour
{
static public CamaraManager instance; // instance의 값을 공유
public GameObject target; // 카메라가 따라갈 대상
public float moveSpeed; // 카메라가 따라갈 속도
private Vector3 targetPosition; // 대상의 현재 위치
// 박스 컬라이더 영역의 최소 최대값
public BoxCollider2D bound;
private Vector3 minBound;
private Vector3 maxBound;
// 카메라의 반넓이와 반높이의 값 변수
private float halfWidth;
private float halfHeight;
// 반 높이를 구하기 위해 필요한 카메라 변수
private Camera theCamera;
private void Awake()
{
if (instance != null)
{
Destroy(this.gameObject);
}
else
{
DontDestroyOnLoad(this.gameObject); // 게임 오브젝트 파괴금지
instance = this;
}
}
// Start is called before the first frame update
void Start()
{
theCamera = GetComponent<Camera>();
minBound = bound.bounds.min;
maxBound = bound.bounds.max;
halfHeight = theCamera.orthographicSize;
halfWidth = halfHeight * Screen.width / Screen.height;
}
// Update is called once per frame
void Update()
{
// 대상이 있는지 체크
if(target.gameObject != null)
{
// this는 카메라를 의미 (z값은 카메라값을 그대로 유지)
targetPosition.Set(target.transform.position.x, target.transform.position.y, this.transform.position.z);
// vectorA -> B까지 T의 속도로 이동
this.transform.position = Vector3.Lerp(this.transform.position, targetPosition, moveSpeed * Time.deltaTime);
float clampedX = Mathf.Clamp(this.transform.position.x, minBound.x + halfWidth, maxBound.x - halfWidth);
float clampedY = Mathf.Clamp(this.transform.position.y, minBound.y + halfHeight, maxBound.y - halfHeight);
this.transform.position = new Vector3(clampedX, clampedY, this.transform.position.z);
}
}
public void SetBound(BoxCollider2D newBound)
{
bound = newBound;
minBound = bound.bounds.min;
maxBound = bound.bounds.max;
}
}
카메라 스크립트에 SetBound라는 바운드 이동 함수가 추가되었습니다.
그림과 같이 A bound의 카메라 영역이 Map 이동시 B bound로 이동하게 됩니다.
3.Scene 이동 카메라 영역 추가
Map이동뿐만 아니라 Scene 이동으로 된 맵에서 카메라 영역 추가가 필요합니다.
Map 이동과 동일하게 이동된 Scene에 빈 객체 영역을 추가합니다.
해당 객체에 박스 콜라이더를 추가하고 새로운 스크립트 파일을 생성합니다.
Bound.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bound : MonoBehaviour
{
// Start is called before the first frame update
private BoxCollider2D bound;
private CamaraManager theCamera;
void Start()
{
bound = GetComponent<BoxCollider2D>();
theCamera = FindObjectOfType<CamaraManager>();
theCamera.SetBound(bound); //카메라 스크립트 파일에 있는 바운드 함수 실행
}
// Update is called once per frame
void Update()
{
}
}
Scene 이동이 일어나게 되면 Map 이동때와 마찬가지로 SetBound 함수를 실행하여 카메라 영역을
변경하게 됩니다.