NGUI 屏幕自适应(初始设定宽高800x480只支持比其大的屏幕)

自适应讲解部分可以参考以下网址:http://www.xuanyusong.com/archives/2536,下面代码中提到的AdaptiveManualHeight()函数就是参考该文章的。

下面主要说的就是背景图、全屏透明Sprite和控件位置自适应的东西。

由于我们所要开发的游戏只支持800x480及以上的分辨率的手机,因此分辨率小于800x480的自适应这里不考虑(其实都差不多的,就是多了一个if判断,然后分别调整下背景图、全屏透明背景而已)

见下图,背景图和全屏sprite(这里为了方便观看,背景图和全屏sprite就没重叠,且全屏sprite设置成透明灰色而不是完全透明)不是父子关系,处于九宫格位置的控件可以使用Anchors来固定在屏幕中的相对位置,UIRoot的Scaling Style属性选择FixedSizeOnMobiles(PS:这个属性要再IOS或者Android平台上才能起作用,为什么可以看UIRoot里面的代码有条件编译,我是在BlueStacks安卓模拟器上运行此测试案例的),ManualHeight就是你实际设计UI时定的高度(可参照上面网址中雨凇momo所讲解的)

NGUI 屏幕自适应(初始设定宽高800x480只支持比其大的屏幕)

首先确定设计时用的宽高为designWidth、designHeight;实际屏幕宽高为realScreenWidth、realScreenHeight;

widthScale = realScreenWidth/designWidth;

heightScale = realScreenHeight/designHeight;

1.因为实际游戏中,背景图一般都是带有不规则图案的(如果宽高不是等比缩放的话,则图案就会变形),因此背景图按照widthScale 与heightScale之间的大者进行缩放(比如设计时定下的屏幕宽高为800x480,实际手机分辨率960x640,那960/800=1.2, 640/480=1.333,那么此时取1.333为背景图的缩放值),这样的话背景图就能铺满整个屏幕不会出现黑边且不变形,但是一般会超出屏幕,这个时候可以让背景图居中(当然了,需要让美术在设计的时候将背景图的重点图案放在中间,边角位置不要放重点图案,这样的话背景图的边缘位置就不会有什么重要信息,也就是发生裁切了也没什么关系)

2.由于游戏中处于九宫格位置的(比如左上角、左下角、右上角、右下角、还有中间、左中间等等其他的区域)控件需要贴着屏幕边缘,这个时候就是要用锚点Anchors(其Target在本例中是指FullScreenSprite)来自动调整,而此时完全透明的Sprite(UIRoot中的ManualHeight缩放起作用之后,将Sprite拉伸至整个屏幕)就起了这个作用,除了背景图外的所有控件都是全透明Sprite的子控件。这样UIRoot缩放起作用之后处于九宫格位置的控件也可以贴边!

具体的见以下代码吧:

 using UnityEngine;
 using System.Collections;
 using System;

 public class Test : MonoBehaviour
 {
     public UIRoot mUIRoot = null;
     public UISprite mBackgroundSprite = null;
     public UISprite mFullScreenSprite = null;

     ;
     ;
     ;
     ;

     private readonly float mWidthScale = Convert.ToSingle(Screen.width) / cDesignWidth;
     private readonly float mHeightScale = Convert.ToSingle(Screen.height) / cDesignHeight;

     void Awake()
     {
         CalculateScreenWidthHeight();
     }

     void Start()
     {
         Assert.IsNotNull(mUIRoot, "Test.Start(), mUIRoot is null");
         Assert.IsNotNull(mBackgroundSprite, "Test.Start(), mBackgroundSprite is null");
         Assert.IsNotNull(mFullScreenSprite, "Test.Start(), mFullScreenSprite is null");

         AdaptiveManualHeight(mUIRoot);
         AdaptiveBackgroundSprite(mBackgroundSprite);
         AdaptiveFullScreenSprite(mFullScreenSprite);
     }

     private void CalculateScreenWidthHeight()
     {
         float scale = (float)mUIRoot.activeHeight / Screen.height;
         mRealScreenWidth = Mathf.CeilToInt(Screen.width * scale);
         mRealScreenHeight = Mathf.CeilToInt(Screen.height * scale);
     }

     public void AdaptiveManualHeight(UIRoot uiRoot)
     {
         Assert.IsNotNull(uiRoot, "Test.AdaptiveManualHeight(), uiRoot is null");
         if (Convert.ToSingle(Screen.height) / Screen.width > Convert.ToSingle(cDesignHeight) / cDesignWidth)
         {
             uiRoot.manualHeight = Mathf.RoundToInt(Convert.ToSingle(cDesignWidth) / Screen.width * Screen.height);
         }
         else
         {
             uiRoot.manualHeight = cDesignHeight;
         }
     }

     //自适应背景图,按宽宽比、高高比的大者缩放
     public void AdaptiveBackgroundSprite(UISprite backgroundSprite)
     {
         //此if语句针对屏幕宽或高大于设计时所定的宽或高
         if (mRealScreenWidth > backgroundSprite.width || mRealScreenHeight > backgroundSprite.height)
         {
             int adaptiveHeight = Mathf.RoundToInt(cDesignHeight * mHeightScale);
             int adaptiveWidth = Mathf.RoundToInt(cDesignWidth * mHeightScale);
             if (mHeightScale <= mWidthScale)
             {
                 adaptiveHeight = Mathf.RoundToInt(cDesignHeight * mWidthScale);
                 adaptiveWidth = Mathf.RoundToInt(cDesignWidth * mWidthScale);
             }
             backgroundSprite.SetDimensions(adaptiveWidth, adaptiveHeight);
         }
     }

     public void AdaptiveFullScreenSprite(UISprite fullScreenSprite)
     {
         fullScreenSprite.SetDimensions(mRealScreenWidth, mRealScreenHeight);
     }
 }

上面代码我在很多分辨率下都测试过(当然要是大于等于800x480的分辨率),如果要支持800x480以下分辨率的,那么自己修改函数

AdaptiveBackgroundSprite(),就是加个else语句做多个调整。

如果存在什么问题或者更好的建议麻烦告知,不胜感激!
上一篇:近期H5项目开发小结


下一篇:Winform界面中实现通用工具栏按钮的事件处理