Skip to content

Instantly share code, notes, and snippets.

@niwatly
Created June 24, 2019 15:13
Show Gist options
  • Save niwatly/1616d794ddfc7a02bc504bb0eee65f6a to your computer and use it in GitHub Desktop.
Save niwatly/1616d794ddfc7a02bc504bb0eee65f6a to your computer and use it in GitHub Desktop.
WorldSpaceでもマルチ解像度に対応したいスクリプトです
using System.Linq;
using UnityEngine;
namespace Btf.View
{
public class DynamicScreenView : MonoBehaviour
{
[SerializeField]
[Tooltip("端末サイズに合わせて拡大/縮小したいRectを設定します")]
public RectTransform screenRect;
[SerializeField]
[Tooltip("縦横比を維持したまま端末にちょうど収まるように拡大/縮小したいRectを設定します")]
public RectTransform contentRect;
[SerializeField]
[Tooltip("縦横比を維持したまま端末にちょうど収まるように拡大/縮小したいRectを設定します。\n調整したいRectが複数ある時に便利なパラメータです")]
public RectTransform[] subContentRects;
[SerializeField]
[Tooltip("Contentがちょうど収まるように調整済みのカメラを設定します")]
public Camera cam;
private void Awake()
{
AdjustScreenAndContentToViewPort();
}
private void AdjustScreenAndContentToViewPort()
{
//カメラの描画範囲(ViewPort空間におけるサイズ)のサイズを取得する
float viewportWidth, viewportHeight;
{
var cameraPositionLeftTop = cam.ViewportToScreenPoint(Vector3.zero);
var cameraPositionRightBottom = cam.ViewportToScreenPoint(Vector3.one);
var cameraDistance = cameraPositionRightBottom - cameraPositionLeftTop;
viewportWidth = cameraDistance.x;
viewportHeight = cameraDistance.y;
}
//Debug.Log($"viewport: width = {viewportWidth}, height = {viewportHeight}, ratio = {viewportWidth / viewportHeight}");
//world空間におけるScreenのサイズをカメラの描画範囲に合わせる
float screenWidth, screenHeight;
{
var screenSize = screenRect.sizeDelta;
//ViewPort上のheightとworld space上におけるheightが等しくなるようCameraを調整してあるので、比でwidthを求める
//
//viewportWidth: viewportHeight = screenWidth: ScreenHeight
screenWidth = screenSize.y * viewportWidth / viewportHeight;
screenHeight = screenSize.y;
screenRect.sizeDelta = new Vector2(screenWidth, screenHeight);
}
//Debug.Log($"screen: width = {screenWidth}, height = {screenHeight}, ratio = {screenWidth / screenHeight}");
//world空間におけるContentのサイズをアスペクト比を維持しつつ収まる最大サイズに変更する
var distanceBetweenCamAndScreen = (cam.transform.position - screenRect.transform.position).magnitude;
var contents = (subContentRects ?? Enumerable.Empty<RectTransform>()).Append(contentRect).Where(x => x != null);
foreach (var content in contents)
{
var distanceBetweenCamAndContent = (cam.transform.position - content.transform.position).magnitude;
var contentShrinkRatio = distanceBetweenCamAndContent / distanceBetweenCamAndScreen;
var contentSize = content.sizeDelta;
//横方向にどれくらい伸びしろがあるか(負値ははみ出していることを意味する)
var widthMargin = screenWidth - contentSize.x;
//縦方向にどれくらい伸びしろがあるか(負値ははみ出していることを意味する)
var heightMargin = screenHeight - contentSize.y;
//伸びしろの少ない方に合わせて拡大/縮小する
var ratio = widthMargin < heightMargin
? screenWidth / contentSize.x
: screenHeight / contentSize.y
;
ratio *= contentShrinkRatio;
//Debug.Log($"content: width margin = {widthMargin}, height margin {heightMargin} width ratio = {screenWidth / contentSize.x}, height ratio = {screenHeight / contentSize.y}");
content.localScale = new Vector3(ratio, ratio, ratio);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment