2014-11-03 20:58:07 qinglongyanyuezhu 阅读数 3649


NGUI是unity3D开发中常用的UI制作插件,它提供了丰富的UI组件,为开发者提供了极大的方便。作为一个手游开发者,面对纷繁复杂的机型,UI的自适应是一个很大的问题,还好NGUI为广大开发者提供了非常方便的自适应解决方案。


在NGUI的整个UI框架中,UIRoot是必不可少的,UI视口的大小是由 NGUI的UIRoot脚本决定的。NGUI的其他控件,如 UIPanel UITexture UISprite UIlabel 等组件,都是继承自UIRect组件,这些组建在Inspector面板中都能够看到Anchor选项,可以选择对应的自适应模式:

None即不进行自适应,不管屏幕分辨率怎么改变,位置保持不变;

Unified 标准自适应,选择后可以选择一个Target,及相对于target的上下左右偏移量,当分辨率改变或者target的尺寸发生变化的时候,UIRect会根据相对于Target的偏移量进行相应的移动缩放等变化。

Advance,上下左右四个边可以分别指定一个Target,当然也可以不指定。


在NGUI3.7.x之前的版本中,UIRoot的 ScalingStyle 由三种不同的选项:

PixelPerfect,

FixedSize,

FixedSizeOnMobiles


PixelPerfect 就是UI显示以图片的真实像素为准,在Minimum Hight 和Maximum Hight 范围内,不进行缩放,图片是多大就是多大,当超过这个范围后,就以此最小值,或最大值的显示范围为准。


FixedSize 也即UI根据设备当前的分辨率自动进行缩放。

FixedSizeOnMobiles 是以上两种的结合,当程序运行在android iOS wp 等移动设备上时,使用FixedSize 模式,其他情况下使用PixelPerfect模式。

因在移动设备中PixelPerfect模式不常用,这里重点说明下FixedSize 模式下的自适应方案。

在FixedSize模式下,UIRoot有个Manual Height 参数,这个就是参考屏幕的高度,在横屏模式下,如果游戏的UI设计是以960*640分辨率为基准的,那么这个值就填640,那么不管在任何分辨率下,都会保证高度不变,宽度根据实际分辨率的比例扩大显示范围,如在1136 * 640分辨率下,显示范围就是1136 * 640 ,在854 * 480 分辨率下,根据显示高度为640,那么宽度就是(640 /480)*854 = 1138.66666,显示范围就是1138*640。为了使在不同分辨率下都能显示背景图,往往会吧背景图做的大一些,以下是不同分辨率下的效果图,图中左中右三个小图片分别根据anchor设置居左对齐,无 ,右对齐:

背景图: 



960*640分辨率下:


 1136*640下:



854* 480下: 




 

以上三种分辨率中,宽高比:

960*640 :1.5,

1136*640 :1.775,

854*480:1.779,

因为我们的UI都是以960*640为基准设计的,当在1136*640和854*480这些宽高比大于960*640的时候,视口范围会自动向两边扩展,按钮等组建也会随之向两边扩展,那么问题来了!1024*768分辨率宽高比:1.33333,小于1.5,视口依旧是高度不变,宽度缩小,就出现了下面的情况:

 

因为宽度缩小,按钮依旧是左/ 右对齐,就会导致按钮相互重叠!

出现这种问题怎么办?如果我们以1024*768分辨率做为参考分辨率,那么所有其他的宽高比大于1.333的分辨率下都是宽度向两边扩展,貌似不会出现重叠的问题,但是如果分辨率宽高比比这个更小呢(虽然现在貌似除了黑莓的一款方屏手机外木有其他的奇葩机型了)?并且现在市面上流行的几种分辨率宽高比基本上都在1.7以上,如果以4:3为比例设计UI的话,放在1.7以上的手机上可能会显得比较松散,效果也不够好。最好的解决办法,就是在宽高比小于基准分辨率的宽高比的情况下,使用基于宽度的缩放模式,反之使用基于高度的缩放模式。

在NGUI3.7.0以前,NGUI并没有提供基于宽度缩放的模式,我们就要自己实现了,这个网上也有较多的解决方案,原理都是一样的,基于宽度缩放,几保证宽度960不变,那么在1024*768屏幕下,高度应该为960*3/4 = 720,也就是当我们把UIRoot的ManualHeight设置为720的时候就能保证在此分辨率下是基于高度缩放了。下边是个人根据网上的方案修改的一个脚本:

public class AutoScale : MonoBehaviour
{

    static int SCREEN_WIDTH = 960;
    static int SCREEN_HEIGHT = 640;
    int mScreenWidth;
    int mScreenHeight;

    UIRoot root;
    // Use this for initialization
    void Awake()
    {
        mScreenWidth = SCREEN_WIDTH;
        mScreenHeight = SCREEN_HEIGHT;
        root = GetComponent<UIRoot>();
ScaleScreen ();
#if UNITY_EDITOR
UICamera.onScreenResize += ScaleScreen;
#endif
    }

    void ScaleScreen()
    {
        if ((float)Screen.width / (float)Screen.height < (float)SCREEN_WIDTH/(float)SCREEN_HEIGHT)
        {
            root.manualHeight = SCREEN_WIDTH * Screen.height / Screen.width;
        }
        else
        {
            root.manualHeight = (int)SCREEN_HEIGHT;
        }
    }



将这个脚本挂在UIRoot所在的物体下,在游戏开始运行时回自动调整UIRoot到合适的值,在编辑器模式下,如果手动调整分辨率会调用UICamera.onScreenResize委托,此时UIRoot也会重置,便于调试。


在NGUI3.7.0版本中,NGUI的开发人员终于意识到了这种自适应方式的优势,于是在UIRoot中新增了基于宽度缩放的模式,在新版本中,ScaleStyle枚举变成了以下三个:

Flexible,

Constrained,

ConstrainedOnMobiles,

实质上跟以前的版本一个意思,只是在Constrained模式下多了两个选项:

 




ContentWidth 基于宽度缩放,ConentHeight,基于高度缩放,Fit后边的勾表示选择的模式,若只打一个勾就是基于宽度或高度缩放,若两个勾都打上,则会根据所填的960 640为基准,如果宽高比大于1.5就基于高度缩放,反之基于宽度缩放,非常之方便。

最后,关于背景图的大小,宽高比最大的分辨率应该是854*480:1.779,最小的应该是1024*768:1.33333在基于960*640为基准分辨率的模式下,那么为保证在这两者范围内的所有分辨率都能够完美显示背景,背景的大小,至少应是1.779*640 = 1138.56,960/1.333 = 720。这样,设置好UIRoot并且调整好各个组件的相对位置,你的游戏就可以在任意分辨率下完美运行了!

2013-03-11 11:48:31 fzhlee 阅读数 5502
用Unity开发移动平台的游戏  不可避免的会遇到屏幕分辨率的问题  
不同的分辨率上会使得原本正常的UI变得乱七八糟  
我们知道  在Unity中可以拿一个plane作为背景 UI则是绘制在离摄像机最近的位置  可以认为是绘制在摄像机上的
因此分辨率的不同会导致UI的位置和大小出现错误

我们完全可以用一个plane去模拟button  并将它放在世界空间中  这样虽然可以解决位置和大小的问题  但是所带来的问题也一大堆并难于维护
因此我们需要根据屏幕的大小去按比例缩放UI
假如原本有个按钮是这样,并且当前的480x854分辨率下没问题,如果改成600x1024或者其他的分辨率,便会发现位置和大小都不正确了

function OnGUI ()
{
     if (GUI.Button(Rect(Screen.width - 200, Screen.height - 100, 64, 64), "Start"))
     {
       // dosomething
     }
}

于是我们按比例去移动和缩放UI

// original screen size
var m_fScreenWidth  : float = 480;
var m_fScreenHeight : float = 854;

// scale factor
var m_fScaleWidth  : float;
var m_fScaleHeight : float;

function Awake ()
{
     m_fScaleWidth = parseFloat(Screen.width)/m_fScreenWidth;
     m_fScaleHeight = parseFloat(Screen.height)/m_fScreenHeight;      
}

function OnGUI ()
{
     if (GUI.Button(Rect(Screen.width - 200 * m_fScaleWidth , Screen.height - 100 * m_fScaleHeight , 64 * m_fScaleWidth , 64 * m_fScaleHeight ), "Start"))
     {
       // dosomething
     }
}

若UI控件较多的时候,对每一个都去控制大小显然没必要
则使用矩阵实现

GUI.matrix = Matrix4x4.TRS (Vector3(0, 0, 0), Quaternion.identity, Vector3 (m_fScaleWidth, m_fScaleHeight, 1)); 

这样就将button的位置和大小都按照比例缩放了  很简单


2018-09-12 11:36:12 oyang_mrong 阅读数 539

unity3d中针对UI界面的自适应问题,其内嵌了自己的算法,如何使用它的算法呢?

很简单!!!

找到Canvas的属性界面中的Canvas Scaler

其中将UI Scale Mode设置为:Scale With Screen Size,将Reference Resolution中x,y设置为主流分辨率(如1920*1080)(Reference Resolution的作用为:当build后的程序在不同分辨的程序下运行时其UI组件的大小会进行自适应操作,其自适应的标准就是UI组件在Reference Resolution中所设置的x,y分辨率下的大小);

2018-07-26 22:25:27 qq_36946274 阅读数 680

今天用UNITY开发游戏,游戏发布后,总是出现游戏画面与测试时画面不符的情况,进行过各种钻研,以及从网上收集资料,终于解决了问题,下面把总结的知识分享一下:
1.所谓的自适应,就是:

a.保持相对位置不变。例如UI设计在屏幕的左上角,那么在各种的分辨率下都应该在左上角

b.保持宽高比例不变。由于分辨率有很多种,所以保持宽高等比例缩放是做不到的,要么是宽拉伸缩放的程度大些,要么是高拉伸缩放的程度大些

2.在UGUI中,可以通过设置UI的描点来设置UI的相对位置;可以通过设置Canvas下的Canvas Scaler来设置UI的缩放比例(Canvas下的Canvas是用来处理UI遮挡关系的)

3.Canvas Scaler组件:

a.当UIScaleMode为Constant Pixel Size时,UI在任何分辨率下都不会进行缩放拉伸,只有通过改变Scale Factor才会进行缩拉,因此不推荐使用该模式(而这种模式的优点就是你可以通过写自适应算法来改变Scale Factor的值,代替unity的自适应算法)

b.当UIScaleMode为Scale With Screen Size时,相当于使用unity的自适应算法,此时unity会根据屏幕分辨率自动调节Scale Factor的值。在做自适应时,一般要先选择一种比较主流的分辨率(即比较多的机型都采用这种分辨率)进行UI的设计,例如采用1024x576,在这里就是设置Reference Resolution的值了。

然后就是Screen Match Mode这个东西了:

当值为Match Width Or Height时:当值为0即处于Width那端时,表示屏幕高度对于UI大小完全没有任何影响,只有宽度会对UI大小产生影响。例如设置屏幕为800*600,然后改变为800*300,屏幕高度变小了,但UI并没有进行缩拉;同理当值为1即处于Height那端时,表示屏幕宽度对于UI大小完全没有任何影响,只有高度会对UI大小产生影响

当值为Expand时:举个例子,设计了一个button宽高为200*100,即宽高比为2:1,放在4:3的屏幕内;然后把这个button放在16:9的屏幕内,显然地,此时button是不能进行等比例的缩放的,即无法保持2:1的宽高比了,Expand的意思就是尽可能地使UI拉伸来适应屏幕

当值为Shrink时:同理,就是尽可能地使UI缩放来适应屏幕

4.一般来说,比较不错的设置就是:

Canvas Scaler 选择 Scale With Screen Size

Screen Match Mode 选择 Match Width Or Height,比例设为1,即只和高度进行适配
这里写图片描述

PS:最后的最后,如果你用了上述所有方法都不好使,你可以试试把你场景里想偏移的物体集体选中,然后统一位移试试。

2019-10-06 12:15:01 weixin_43352477 阅读数 74

经常会用到Unity 自适应的问题,今天来总结以下三点。

1.UI控件自适应

UI控件(Button,Image等)的自适应是用的最多的,通常通过锚点的设定,来完成UI控件的适应。根据UI控件需要锁定的不同位置,设置锚点的位置。
在这里插入图片描述

2.Canvas自适应

不同的设备,分辨率不同,这时候Canvas需要根据不同的分辨率缩放,需要设置Canvas组件上的Canvas Scale脚本 的UI Scale Mode 模式为Scale With Screen Size。并根据自己屏幕的需要设置Reference Resolution的值。
在这里插入图片描述

3.视口自适应

Unity 在默认情况下,已经做了视口自适应(以高度为准,对宽度进行缩放或者剪裁)。
但是在一些特殊情况下需要以宽度为准。这就需要我们通过代码控制了。
视口自适应在一些情况下可以与屏幕自适应达到相同的效果。

Unity3D UGUI自适应

阅读数 170

Unity3d NGUI伪自适应

阅读数 596

没有更多推荐了,返回首页