原地址:http://www.2cto.com/kf/201310/250921.html

一、当下移动设备的主流分辨率(数据来自“腾讯分析移动设备屏幕分辨率分析报告”)

1.1 iOS设备的分辨率主要有:
 
宽  高 宽高比
960 640 1.5
1136 640 1.775
1024 768 1.3333
2048 1536 1.3333
 
Android设备的分辨率则相对纷杂,主流的分辨率有:
宽 高 宽高比
800 480 1.6667
854 480 1.7792
1280 720 1.7778
960 540 1.7778
1280 800 1.6
960 640 1.5
1184 720 1.6444
1920 1080 1.7778
 
 
二、NGUI默认的多分辨率适配原则
NGUI本身按照“高度适配”的原则进行多分辨率下的UI适配,其默认的高度通过 UIRoot.manualHeight 设置。再配合使用 UIAnchor 便可实现一定程度的多分辨率适配。
 
其中,在Unity Editor下按照 UIRoot.manualHeight 设定的高度,编辑UI页面。这样,当UI页面在目标设备上显示时,NGUI按照目标设备的高度(targetHeight)来调整UIRoot节点的scale,以使整个UI页面适应目标设备的高度。比如manualHeight=400,而targetHeight=800,那么UIRoot的scale将被乘以2。所以,当目标设备的宽高比与所编辑页面的宽高比一致时,整个UI将完美显示;当目标设备宽高比小于所编辑的宽高比时,页面宽度将大于设备宽度,使得多出的部分无法显示;而当目标设备宽高比大于所编辑宽高比时,页面宽度小于设备宽度,设备两边将出现黑边。
 
而UIAnchor则是将整个页面分为TopLeft/Top/TopRight/Left/Center/Right/BottomLeft/Bottom/BottomRight九个区域,挂载了UIAnchor组件的节点都将按照设置自动停靠到相应的区域中。有了UIAnchor,上面的两个问题将被一定程度的解决:当目标设备宽高比小于编辑的宽高比时,由于UIAnchor的自动停靠功能,UI不会被裁切掉,但UI之间的左右间距将相应变小,便有可能出现UI重叠的问题;当目标设备宽高比大于所编辑宽高比时,UI之间的左右间距将变大,好在这样起码不会有UI被裁切或重叠。
 
看似我们只需要解决UI重叠的问题就搞定了。不过让我们再仔细想一下,一张铺满整个屏幕的UISprite不管是否使用UIAnchor,在目标设备宽高比更小时,sprite都会在横向上被裁切,而将目标设备宽高比更大时,sprite都不能铺满整个屏幕。
 
问题出来了:
1. 当目标设备宽高比更小时的UI重叠问题
2. 当目标设备宽高比更小时,全屏sprite被裁切问题
3. 当目标设备宽高比更大时,全屏sprite不能铺满整个屏幕的问题
 
 
三、解决问题
首先定义几个变量:
standard_width  编辑页面的原始宽度
standard_height  编辑页面的原始高度
device_width    目标设备的宽度
device_height    目标设备的高度
standard_aspect  编辑页面的宽高比
device_aspect    目标设备的宽高比
 
1. 目标设备宽高比更小时的UI重叠问题
  当device_aspect小于standard_aspect时,UIRoot根据device_height调整其scale大小,因而使得设备宽度不足以显示整个页面。我们调整Camera.orthographicSize(仅适用2D GUI),以足够显示页面的宽度。令
  Camera.orthographicSize = standard_aspect / device_aspect;
即,改变了NGUI原有的“高度适配”原则,转为“宽度适配”,使得整个页面都得以显示,而由于UIAnchor的存在,UI的左右间距保持不变,但上下间距会变大。
该方法可以实现为一个MonoBehaviour脚本(UICameraAdjustor.cs),挂载到UICamera同一个节点上,代码如下:
 
 
 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 /// <summary>
 5 /// 根据设备的宽高比,调整camera.orthographicSize. 以保证UI在不同分辨率(宽高比)下的自适应
 6 /// 须与UIAnchor配合使用
 7 /// 将该脚本添加到UICamera同一节点上
 8 /// </summary>
 9 
10 [RequireComponent(typeof(UICamera))]
11 public class UICameraAdjustor : MonoBehaviour
12 {
13     float standard_width = 1024f;
14     float standard_height = 600f;
15     float device_width = 0f;
16     float device_height = 0f;
17 
18     void Awake()
19     {
20         device_width = Screen.width;
21         device_height = Screen.height;
22 
23         SetCameraSize();
24     }
25 
26     private void SetCameraSize()
27     {
28         float adjustor = 0f;
29         float standard_aspect = standard_width / standard_height;
30         float device_aspect = device_width / device_height;
31 
32         if (device_aspect < standard_aspect)
33         {
34             adjustor = standard_aspect / device_aspect;
35             camera.orthographicSize = adjustor;
36         }
37     }
38 }
 
 
 
总之,在使用该方法后,当device_aspect大于standard_aspect时,UI按照高度适配原则,UI的上下间距不变,左右间距变大;当device_aspect小于standard_aspect时,UI按照宽度适配原则,UI的左右间距不变,上下间距变大。
 
2. 目标设备宽高比更小时,全屏sprite被裁切问题
  全屏背景的sprite被裁切可能在很多情况下不会成为什么问题,但在我们使用了解决问题1中的方法后,这里的“被裁切问题”就变为了同问题3类似的“不能铺满整个屏幕问题”。解决方法是放大sprite scale:
  sprite.transform.localScale *= ( standard_aspect / device_aspect );
这样会使得sprite在横向上被裁切,宽高比不同必然的结果... 当然也可以选择只调整高度或宽度,只要能接受变形...
 
3. 目标设备宽高比更大时,全屏sprite不能铺满整个屏幕的问题
   同问题2,解决方法同样是放大sprite scale:
  sprite.transform.localScale *= ( device_aspect / standard_aspect );
这样会使得sprite在纵向上被裁切。
 
问题2和3的解决方法相应脚本(UIBackgroundAjustor.cs)会在文章后面给出。
该脚本须挂载到sprite同一节点上,配合UIAnchor使用,可以选择是裁切方向。如UIAnchor停靠方式使用center,则sprite会被左右两边或上下裁切,若使用Top,则会左右裁切或下边裁切。
总之,全屏sprite会始终铺满整个屏幕,不会出现黑边。当device_aspect大于standard_aspect时,全屏sprite按照宽度适配,纵向裁切;当device_aspect小于standard_aspect时,按照高度适配,横向裁切。
 
四、优化
1. UI页面的制作尺寸按 1024 X 600
  前面讲到主流分辨率的情况,其平均宽高比(除ipad2/3/4以外)大概为1.7,与主流的宽高比都不会偏差很大。即,在使用上面的多分辨率解决方法时,UI不会在纵向或横向上的间距过大,显得特别离谱。按照此宽高比,我们选择1024x600的尺寸来制作UI,并严格要求UI制作时,页面分为TopLeft/Top/TopRight/Left/Center/Right/BottomLeft/Bottom/BottomRight九个区域,以便挂载UIAnchor。
 
2. 全屏背景的制作按 1024 X 768
  如果全屏背景图也按1024 x 600制作,在ipad2/3/4上就会有较大程度的放大。同时考虑到NGUI的打包atlas,使用2的幂次尺寸,高度600和768都将占用1024x1024的atlas。所以全屏背景在制作时,高度上做出一定的冗余尺寸,以使宽高比小于1.7时,高度上放大系数不会太大,避免图片严重失真。
  加入冗余尺寸后的脚本(UIBackgroundAjustor.cs)如下:
 
 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 /// <summary>
 5 /// 根据设备的宽高比,调整UISprite scale, 以保证全屏的背景图在不同分辨率(宽高比)下的自适应
 6 /// 将该脚本添加到UISprite同一节点上
 7 /// 须与UICameraAdjustor脚本配合使用
 8 /// </summary>
 9 
10 [RequireComponent(typeof(UISprite))]
11 public class UIBackgroundAdjustor : MonoBehaviour
12 {
13     float standard_width = 1024f;
14     float standard_height = 600f;
15     float device_width = 0f;
16     float device_height = 0f;
17 
18     void Awake()
19     {
20         device_width = Screen.width;
21         device_height = Screen.height;
22 
23         SetBackgroundSize();
24     }
25 
26     private void SetBackgroundSize()
27     {
28         UISprite m_back_sprite = GetComponent<UISprite>();
29 
30         if (m_back_sprite != null && UISprite.Type.Simple == m_back_sprite.type)
31         {
32             m_back_sprite.MakePixelPerfect();
33             float back_width = m_back_sprite.transform.localScale.x;
34             float back_height = m_back_sprite.transform.localScale.y;
35 
36             float standard_aspect = standard_width / standard_height;
37             float device_aspect = device_width / device_height;
38             float extend_aspect = 0f;
39             float scale = 0f;
40 
41             if (device_aspect > standard_aspect) //按宽度适配
42             {
43                 scale = device_aspect / standard_aspect;
44 
45                 extend_aspect = back_width / standard_width;
46             }
47             else //按高度适配
48             {
49                 scale = standard_aspect / device_aspect;
50 
51                 extend_aspect = back_height / standard_height;
52             }
53 
54             if (extend_aspect >= scale) //冗余尺寸足以适配,无须放大
55             {
56             }
57             else //冗余尺寸不足以适配,在此基础上放大
58             {
59                 scale /= extend_aspect;
60                 m_back_sprite.transform.localScale *= scale;
61             }
62         }
63     }
64 }

Unity3d + NGUI 的多分辨率适配(黑边)的更多相关文章

  1. 【转】Unity3d + NGUI 的多分辨率适配

    原文地址:http://www.cnblogs.com/cqgreen/p/3348154.html   一.当下移动设备的主流分辨率(数据来自“腾讯分析移动设备屏幕分辨率分析报告”) 1.1 iOS ...

  2. Unity3d + NGUI 的多分辨率适配

    一.当下移动设备的主流分辨率(数据来自“腾讯分析移动设备屏幕分辨率分析报告”) 1.1 iOS设备的分辨率主要有:   宽 高 宽高比 960 640 1.5 1136 640 1.775 1024 ...

  3. Unity NGUI的多分辨率适配

    参考链接:http://blog.csdn.net/mfc11/article/details/17681429,作者:CSDN mfc11 1.NGUI默认的适配方式: NGUI默认是适配方式是根据 ...

  4. Unity3d + UGUI 的多分辨率适配

    原文地址:http://blog.csdn.net/dingkun520wy/article/details/49471789 1.Canvas的属性配置 2.Canvas Scaler的属性配置 3 ...

  5. Cocos与Cocos2d-x协作教程——多分辨率适配

    http://www.cocoachina.com/bbs/read.php?tid-288123.html Cocos v2.1开始新增了一种新的多分辨率适配方案:流式布局. 这种布局相比Cocos ...

  6. Unity3D NGUI自适应屏幕分辨率(2014/4/17更新)

    原地址:http://blog.csdn.net/asd237241291/article/details/8126619 原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 本文链接地址: ...

  7. Cocos2d-x 多分辨率适配完全解析

    从Cocos2d-x 2.0.4开始,Cocos2d-x提出了自己的多分辨率支持方案,废弃了之前的retina相关设置接口,提出了design resolution概念. 有以下相关接口: CCEGL ...

  8. (16)Cocos2d-x 多分辨率适配完全解析

    Overview 从Cocos2d-x 2.0.4开始,Cocos2d-x提出了自己的多分辨率支持方案,废弃了之前的retina相关设置接口,提出了design resolution概念. 3.0中有 ...

  9. 【Cocos2d-x 017】 多分辨率适配全然解析

    转:http://blog.csdn.net/w18767104183/article/details/22668739 文件夹从Cocos2d-x 2.0.4開始,Cocos2d-x提出了自己的多分 ...

随机推荐

  1. 淘淘实惠多www.taohuiduo.com-专注独家折扣、1折特卖、9块9包邮、全场包邮

    淘淘实惠多-http://www.taohuiduo.com 专注独家折扣.1折特卖.9块9包邮.品牌折扣.20元封顶.全场包邮,所有的促销商品包括男装.女装.箱包配饰.母婴.日用.化妆品.数码.男鞋 ...

  2. MySQL之经典语句

    数据库的创建:(例如创建名为ConstructionDB的数据库) --创建SelfStudy数据库 CREATE DATABASE ConstructionDB ON PRIMARY --创建主数据 ...

  3. Hibernate+DWR无刷新三级联动

    DWR(Direct Web Remoting)是一个用于改善web页面与Java类交互的远程服务器端Ajax开源框架,可以帮助开发人员开发包含AJAX技术的网站.它可以允许在浏览器里的代码使用运行在 ...

  4. (转)实战Memcached缓存系统(2)Memcached Java API基础之MemcachedClient

    1. 构造函数 public MemcachedClient(InetSocketAddress[] ia) throws IOException; public MemcachedClient(Li ...

  5. 使用百度zrender, demo抛砖引玉.

    http://www.just.org.cn/zrender/index.html https://github.com/ecomfe/zrender 目录结构: |-project    |-dem ...

  6. 线程模式HS/HA和L/F的区别, HS/HA的实现原理图

    线程池模式一般分为两种:L/F领导者与跟随者模式.HS/HA半同步/半异步模式. HS/HA 半同步/ 半异步模式 :分为三层,同步层.队列层.异步层,又称为生产者消费者模式,主线程处理I/O事件并解 ...

  7. 第七章 探秘Qt的核心机制-信号与槽

    第七章 探秘Qt的核心机制-信号与槽 注:要想使用Qt的核心机制信号与槽,就必须在类的私有数据区声明Q_OBJECT宏,然后会有moc编译器负责读取这个宏进行代码转化,从而使Qt这个特有的机制得到使用 ...

  8. rsync命令(同步/备份数据)

    rsync命令rsync命令是一个远程数据同步工具,可通过 lam/wan快速同步多台主机间的文件.rsync使用所谓的 "rsync算法"来使用本地和远程两个主机之间的文件达到同 ...

  9. c# 两个数组比较,将重复部分去掉,返回不重复部分

    List<string> Ashuzu = new List<string>(); Ashuzu.Add("); Ashuzu.Add("); List&l ...

  10. 解决firefox经常出现Adobe Flash 插件已崩溃

    官方解决方法: 方案1:更新 Flash 方案2: 降级到 Flash 10.3 方案3:禁用 Flash 沙箱特性 最近很长一段时间用firefox浏览多个含大量图片和flash视频的网页经常会卡顿 ...