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;
#endif

namespace 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层,底层可以随意拉伸/平铺,上层放场景元素/装饰物。
但是注意:尽量不要使拆分后的总大小 > 原图大小

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NRatel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值