EveryDay.DevUp

[Unity] 프레임워크 개발 - 4. 2D Camera 본문

FrameWork

[Unity] 프레임워크 개발 - 4. 2D Camera

EveryDay.DevUp 2020. 4. 30. 17:26

단말기에 따른 Camera 설정의 이론은 다음의 게시물을 통해 확인 가능

https://everyday-devup.tistory.com/7

 

[Unity] 해상도에 따른 2D Camera 설정

2D 카메라의 Size는 게임의 특징에 따라 가로로 고정 할지 세로로 고정을 할지 결정하게 된다. ( 단말기에 따라 보여지는 최소한의 영역을 보장함으로써 최대한 동등한 플레이를 할 수 있도록 하기 위함 ) ▶ 세..

everyday-devup.tistory.com

● 단말기의 해상도 체크

▶ Unity Editor에서의 Game View 사이즈의 실시간 크기 조정이나, 해상도가 각기 다른 액정을 2개 가지고 있는 단말기 등 다양한 이유로 해상도가 실시간으로 변경되는 경우가 발생

▶ ScreenManager는 Update를 통해 매프레임 해상도의 변화를 체크 후, 사이즈 변경이 발생했을 때 관찰자들에게 해상도가 변경되었다는 점을 공지해줌

◎ Game Script에서 ScreenManager의 Update 매프레임마다 호출 : https://everyday-devup.tistory.com/16

 

[Unity] 프레임워크 개발 - 2. 기본 구조 ( Game Script )

프레임워크의 기본 구조로 Game 이라는 스크립트를 통해 전체 게임 코드를 관리하고자 한다. ▶ Game은 싱글톤으로 구현하여 항상 모든 Scene에 존재할 수 있도록 한다. ( 싱글톤 참조 ) https://everyday-devup...

everyday-devup.tistory.com

옵저버 패턴을 사용 : https://everyday-devup.tistory.com/17

 

[Unity] 프레임워크 개발 - 3. 기본 구조 ( 옵저버 패턴 )

옵저버 패턴 : 변화가 있는 대상과 대상을 관찰하는 관찰자로 이루어지는 구조 ● 옵저버 패턴의 구현 ▶ 사용 예시 : Screen의 크기가 실시간으로 변화 되는지 감지하다가, Screen의 변화가 생기면

everyday-devup.tistory.com

[ 옵저버 패턴의 대상 ]

▶ ScreenManager는 매 프레임마다 Screen의 크기가 달라졌는지 체크 후, 달라졌을 때 관찰자들에게 통보

using UnityEngine;

public class ScreenManager : Subject, IManage
{
	public int ScreenWidth { get; private set; } = 0;

	public int ScreenHeight { get; private set; } = 0;

	public ScreenManager()
	{
		Loop();
	}

	public void Loop()
	{
		if( ScreenWidth != Screen.width || ScreenHeight != Screen.height )
		{
			ScreenWidth = Screen.width;
			ScreenHeight = Screen.height;

			OnNotify();
		}
	}
}

[ 옵저버 패턴의 관찰자]

▶ Camera2D는 Screen의 크기가 변경되었다는 노티를 받으면 현재 카메라의 크기를 해상도에 맞게 변경 후 관찰자들에게 노티

using UnityEngine;

[RequireComponent( typeof( Camera ) )]
public class Camera2D : Subject, IObserver
{
	[HideInInspector]
	public int minWidth;
	[HideInInspector]
	public int minHeight;
	[HideInInspector]
	public bool matchWidth;

	[HideInInspector]
	public int screenWidth;
	[HideInInspector]
	public int screenHeight;

	public int Priority { get; set; }
	public OBSERVER_STATE State { get; set; }

	private Camera _cam;

	public void OnEnable()
	{
		if( Game.Instance == null )
		{
			return;
		}

		ScreenManager screenManager = Game.Instance.screenManager;
		OnScreenSize( screenManager.ScreenWidth, screenManager.ScreenHeight );

		screenManager.AddObserver( this );
	}

	public void OnDisable()
	{
		if( Game.Instance == null )
		{
			return;
		}

		ScreenManager screenManager = Game.Instance.screenManager;
		screenManager.RemoveObserver( this );
	}

	public void OnResponse(object obj)
	{
		ScreenManager screenManager = obj as ScreenManager;
		if( screenManager != null )
		{
			OnScreenSize( screenManager.ScreenWidth, screenManager.ScreenHeight );
		}
	}

	public void OnScreenSize(int screenWidth, int screenHeight)
	{
		if( _cam == null )
		{
			_cam = GetComponent<Camera>();
		}

		if( _cam.orthographic == false )
		{
			_cam.orthographic = true;
		}

		int orthographicSize = GetOrthographicSize( screenWidth, screenHeight );
		_cam.orthographicSize = orthographicSize;

		orthographicSize *= 2;

		this.screenWidth = ( screenWidth * orthographicSize ) / screenHeight;
		this.screenHeight = orthographicSize;

		OnNotify();
	}

	public int GetOrthographicSize(int screenWidth, int screenHeight)
	{
		int orthographicSize = 0;
		float addRate = 0.0f;

		if( matchWidth )
		{
			orthographicSize = Mathf.RoundToInt( ( screenHeight * minWidth ) / screenWidth );
			if( orthographicSize < minHeight )
			{
				addRate = (float)minHeight / orthographicSize;
				orthographicSize = Mathf.RoundToInt( orthographicSize * addRate );
			}
		}
		else
		{
			orthographicSize = minHeight;
			int width = ( screenWidth * minHeight ) / screenHeight;
			if( width < minWidth )
			{
				addRate = (float)minWidth / width;
				orthographicSize = Mathf.RoundToInt( orthographicSize * addRate );
			}
		}

		return Mathf.RoundToInt( orthographicSize * 0.5f );
	}
}

▶ 커스텀 에디터를 활용하여 인스펙터 창에 실행 중일 때 카메라의 사이즈가 나올 수 있도록 함

커스텀 에디터 관련 내용 : https://everyday-devup.tistory.com/19

 

[Unity] Custom Editor ( 커스텀 에디터 )

유니티를 사용하다보면, 익스펙터 창에 추가로 보여주고 싶은 UI가 생길 수 있게 됨 예시 ) Camera2D 스크립트에서 Unity 실행 중에는 변화된 카메라의 사이즈를 보여주고 싶은 경우 실행 전에는 보��

everyday-devup.tistory.com

● 테스트 결과

▶ 18.5 : 9 의 ( 2960 * 1440 ) Game View의 상태, Cube의 크기를 ( 50, 720, 1 )으로 변화된 해상도를 체크하기 위해 테스트로 넣어둠

실행 전 상태
실행 후 상태

▶ 1480 * 720의 사이즈로 변경된 카메라를 볼 수 있으며, 720으로 높이를 맞춰둔 큐브가 카메라에 딱 맞게 들어오는 것을 볼 수 있음