Unity屏幕适配——背景适配
接前两篇
Unity屏幕适配——立项时设置_unity 竖屏-CSDN博客文章浏览阅读1.3k次,点赞25次,收藏6次。其中:1334 是设计高2 是Camera(相机)的Size属性用于定义相机视图的垂直大小。这个值实际上是相机视图的一半高度。100 UI坐标系相对世界坐标系的缩放倍数。_unity 竖屏https://blog.csdn.net/NRatel/article/details/146253789Unity屏幕适配——适配信息计算和安全区域适配-CSDN博客文章浏览阅读34次。3、从屏幕空间到UI空间转换大小时,核心为 / screenScale。EnvelopeParent模式,Screen相对Design的缩放值。EnvelopeParent模式,Canvas相对Design的缩放值。实际屏幕相对于设计的缩放值(与fitInScale相同)FitIn模式,Screen相对Design的缩放值。FitIn模式,Canvas相对Design的缩放值。屏幕空间下,四边安全区域距屏幕边缘的大小。UI空间下,四边安全区域距屏幕边缘的大小。初始化时,需注入的屏幕基本信息的获取接口。
https://blog.csdn.net/NRatel/article/details/148286327背景的适配有以下可能性:
1、纯色
纯色可以直接四角拉伸/设到足够大
应拆出背景上影响拉伸的元素
2、平铺
可沿上下/左右/四方向平铺
应拆出背景上影响平铺的元素
3、九宫
可沿上下/左右/四方向九宫
应拆出背景上影响平铺的元素
4、保持自身宽高比,等比缩放至使自身较大边与屏幕边顶齐,另一边有空白或黑边(FitInParent)(背景图完全适应在屏幕内)。
优点:设计显示部分可完全展示出。
缺点:需要更大的图,整体显示比例可能偏小。
iphoneX 和 ipad air 效果
5、保持自身宽高比,等比缩放至使自身较小边与屏幕边顶齐,另一边超出部分被裁剪(EnvelopeParent)(背景图包着屏幕(父物体))。
优点:图还是设计大小,无需改变。能覆盖所有分辨率(不论效果前提下)。
缺点:不安全,设计显示部分不能完全展示出,整体显示比例可能偏大。
iphoneX 和 ipad air 效果
6、超出设计分辨率,上下左右补图,不缩放
优点:适合内容丰富的背景。
缺点:需要图出得足够大
ipad 要求的最小宽: 1536/(2048/1334) = 1000.5
iphoneX 要求的最小高: 2436/(1125/750) = 1624
出到 1000*1700(需要截断为2部分,使单图不超过1024*1024),市场上常规的屏幕,基本上都是安全的。
但,实际还有更宽或更长的屏待适配
比如折叠屏,展开的时候比pad还宽,折叠的时候比 iphoneX还长。
iphoneX 和 ipad air 效果
折叠屏效果(1000*1700都不够大,上下左右还有黑边)
7、超出设计分辨率,上下左右补图+ 适当大小调整或缩放
在6的基础上做极限适配,消除黑边。
折叠屏效果(没有黑边了)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Reflection;#if UNITY_EDITOR
using UnityEditor;
#endifnamespace NRFramework
{public enum ExtremeBgType{None = 0,ExtremeWide = 1,ExtremeTall = 2,}[RequireComponent(typeof(RectTransform))]public class ExtremeBgAdapter : MonoBehaviour{public enum AdapterType{AdjustRect = 1,AdjustScale = 2,}//背景极限 NativeSize,当 Canvas的宽>此宽 或 Canvas的高 > 此高时,将 AspectRatioFitter 的AspectMode 设为 EnvelopeParent;static public Vector2 kBgExtremeNativeSize = new Vector2(1000, 1700);[SerializeField]private AdapterType m_AdapterType = AdapterType.AdjustRect;private ExtremeBgType m_ExtremeBgType;private float m_EnvelopeScale;private RectTransform m_RectTransform;private void Awake(){m_RectTransform = ((RectTransform)transform);}private void Start(){if (!ScreenAdapter.inited) { return; }DoAdjust();}private void Reset(){if (!ScreenAdapter.inited) { return; }DoAdjust();}private void OnEnable(){if (!ScreenAdapter.inited) { return; }ScreenAdapter.onScreenSizeChanged += DoAdjust;}private void OnDisable(){if (!ScreenAdapter.inited) { return; }ScreenAdapter.onScreenSizeChanged -= DoAdjust;}public void DoAdjust(){Debug.Assert(ScreenAdapter.inited);var canvasSize = ScreenAdapter.canvasSize;if (canvasSize.x > kBgExtremeNativeSize.x){m_ExtremeBgType = ExtremeBgType.ExtremeWide;m_EnvelopeScale = canvasSize.x / kBgExtremeNativeSize.x;}else if (canvasSize.y > kBgExtremeNativeSize.y){m_ExtremeBgType = ExtremeBgType.ExtremeTall;m_EnvelopeScale = canvasSize.y / kBgExtremeNativeSize.y;}else{m_ExtremeBgType = ExtremeBgType.None;m_EnvelopeScale = 1f;}float adjustRect = m_AdapterType == AdapterType.AdjustRect ? m_EnvelopeScale : 1f;float adjustScale = m_AdapterType == AdapterType.AdjustScale ? m_EnvelopeScale : 1f;//Debug.Log($"canvasSize: ({canvasSize.x}, {canvasSize.y})");//Debug.Log($"m_ExtremeBgType: {m_ExtremeBgType}");//Debug.Log($"m_EnvelopeScale: {m_EnvelopeScale}");//Debug.Log($"adjustRect: {adjustRect}");//Debug.Log($"adjustScale: {adjustScale}");m_RectTransform.ResetAnchor();m_RectTransform.ResetLocal();m_RectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, kBgExtremeNativeSize.x * adjustRect);m_RectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, kBgExtremeNativeSize.y * adjustRect);m_RectTransform.localScale = new Vector3(adjustScale, adjustScale, 1);}public ExtremeBgType GetExtremeBgType(){return m_ExtremeBgType;}public float GetEnvelopeScale(){return m_EnvelopeScale;}}[CustomEditor(typeof(ExtremeBgAdapter))]public class ExtremeBgAdapterEditor : Editor{public override void OnInspectorGUI(){serializedObject.Update();// 获取目标组件ExtremeBgAdapter adapter = target as ExtremeBgAdapter;// 检测属性变化EditorGUI.BeginChangeCheck();// 绘制默认属性DrawDefaultInspector();// 结束检测bool hasChanged = EditorGUI.EndChangeCheck();// 如果属性变化或点击按钮时刷新if (hasChanged){adapter.DoAdjust();}serializedObject.ApplyModifiedProperties();}}
}
----------------------------------- NRatel 割 -----------------------------------
不同的背景应按不同需求选择不同的适配方案。
可以在设计界面的时候考虑好,
或者程序在做界面时,与美术挨着对每个界面的适配方式,做一些调整。
尽量避免 上下左右补图 的方案。
这会增加美术工作量、影响包体大小、运行时内存占用、增加GPU压力。
场景型背景可以考虑再拆一成2层,底层可以随意拉伸/平铺,上层放场景元素/装饰物。
但是注意:尽量不要使拆分后的总大小 > 原图大小