自适应讲解部分可以参考以下网址: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所讲解的)
首先确定设计时用的宽高为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语句做多个调整。 如果存在什么问题或者更好的建议麻烦告知,不胜感激!