Unity强制屏幕纵宽比脚本

?Xiaoke's Blog,unity3d中文网站,Unity3D中文网,unity3d中文论坛,unity3d学习社区,unity3d教程,Unity3D教学,Unity3D专业,unity3d中国,unity,unity开发,unity ios,unity android,unity3d游戏,unity游戏,unity3d官网,unity中国官网,Unity强制屏幕纵宽比脚本 - XiaoKe's BlogXiaoKe's
Blog 无止境的夜~瞬息万变~一下开心~一下皱眉~
首页生活琐事日常工作技术日志我的成果杂七杂八访客留言论坛

上一篇 | 下一篇 技术日志
Unity强制屏幕纵宽比脚本作者:威阿 日期:2012-11-22
字体大小: 小 中 大
强制屏幕到所需要的长宽比,可以根据需要自由选择是否应用强制比例.其中包括返回校正后的屏幕宽度,高度(Screen.width/height)和鼠标位置(Input.mousePosition).

将这个脚本放在编译顺序较优先的文件夹中,比如 Standard Assets,
(Plugins是最先编译的),因此你可以用Js,C#等语言调用AspectUtility来使用它.首先要将它附加到Camera上,它同样可以附加给其他物体,如果你赋给其他物体,它将主动尝试找到标签为"Main
Camera"的相机.对于WantedAspectRatio这个值,常见的是4:3为1.333333,16:10为1.6,16:9为1.777778,如果屏幕的纵宽比与设定的相同,不会有任何变化.如果与设定的纵宽比不同,将用黑色填充缺少的部分.
这样会导致有些方法返回不正确,比如Screen.width和Screen.height会返回实际屏幕尺寸,而不是主相机的尺寸,为了纠正这个问题,可以使用AspectUtility.screenWidth和AspectUtility.screenHeight.

同样的,Input.mousePosition也会有些问题,这种情况可以使用AspectUtility.mousePosition获取需要的值.

有一点要注意,这些变量在脚本刚唤醒的时候可能不能正确获取到,这就需要等待脚本开始后再访问它们.

当屏幕尺寸变化,例如Webplayer,采用4:3的比例,用户切换全屏后变成了16:9,这时候就需要用AspectUtility.SetCamera()重设脚本相机.

OnGUI代码在用AspectRatioEnforcer时需要做一些额外的工作.OnGUI的代码独立于Camera画在屏幕上的.所以相机改变了矩阵尺寸,它不会自动变化.这时候我们要特别处理一下.

如果你是用GUILayout来排列GUI,可以用GUILayout.BeginArea和EndArea来定义一个范围,像下面这样:

js 代码
?12345function OnGUI () { https://www.360docs.net/doc/7d7747804.html,bel("Hello"); https://www.360docs.net/doc/7d7747804.html,bel("there");}



修改它为:


js 代码
?12345678function OnGUI () { GUILayout.BeginArea(AspectUtility.screenRect); https://www.360docs.net/doc/7d7747804.html,bel("Hello"); https://www.360docs.net/doc/7d7747804.html,bel("there"); GUILayout.EndArea();}



如果已经用过BeginArea/EndArea,你可以直接在外面再嵌套AspectUtility.screenRect,它仍旧会处理好的.

如果你没有使用GUILayout,那么可以添加x和y的偏移来修正所有GUI的Rect,可以用AspectUtility.xOffset 和
AspectUtility.yOffset来得到偏移量,比如你平时这样写:


js 代码
?12345function OnGUI () {

https://www.360docs.net/doc/7d7747804.html,bel(Rect(50, 50, 100, 30), "Hello"); https://www.360docs.net/doc/7d7747804.html,bel(Rect(75, 75, 100, 30), "there");}



现在改成:


js 代码
?12345678function OnGUI () { var x = AspectUtility.xOffset; var y = AspectUtility.yOffset; https://www.360docs.net/doc/7d7747804.html,bel(Rect(x + 50, y + 50, 100, 30), "Hello"); https://www.360docs.net/doc/7d7747804.html,bel(Rect(x + 75, y + 75, 100, 30), "there");}



通常在OnGUI里获得鼠标位置用的是Event.current.mousePosition,在这里我们应该改使用AspectUtility.guiMousePosition.

AspectUtility.cs脚本

csharp 代码
?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101using UnityEngine; public class AspectUtility : MonoBehaviour { public float _wantedAspectRatio = 1.3333333f; static float wantedAspectRatio; static Camera cam; static Camera backgroundCam; void Awake () { cam = camera; if (!cam) { cam = Camera.main; } if (!cam) { Debug.LogError ("No camera available"); return; } wantedAspectRatio = _wantedAspectRatio; SetCamera(); } public static void SetCamera () { float currentAspectRatio = (float)Screen.width / Screen.height; // If the current aspect ratio is already approximately equal to the desired aspect ratio, // use a full-screen Rect (in case it was set to something else previously) if ((int)(currentAspectRatio * 100) / 100.0f == (int)(wantedAspectRatio * 100) / 100.0f) { cam.rect = new Rect(0.0f, 0.0f, 1.0f, 1.0f); if (backgroundCam) { Destroy(backgroundCam.gameObject); } return; } // Pillarbox if (currentAspectRatio > wantedAspectRatio) { float inset = 1.0f - wantedAspectRatio/currentAspectRatio; cam.rect = new Rect(inset/2, 0.0f, 1.0f-inset, 1.0f); } // Letterbox else { float inset = 1.0f - currentAspectRatio/wantedAspectRatio; cam.rect = new Rect(0.0f, inset/2, 1.0f, 1.0f-inset); } if (!backgroundCam) { // Make a new camera behind the normal camera which displays black; otherwise the unused space is undefined backgroundCam = new GameObject("BackgroundCam", typeof(Camera)).camera; backgroundCam.depth = int.MinValue; backgroundCam.clearFlags = CameraClearFlags.SolidColor; backgroundCam.backgroundColor = Color.black; backgroundCam.cullingMask = 0; } } public static int screenHeight { get { return (int)(Screen.height * cam.rect.height); } } public static int screenWidth { get { return (int)(Screen.width * cam.rect.width); } } public static int xOffset { get { return (int)(Screen.width * cam.rect.x); } } public static int yOffse

t { get { return (int)(Screen.height * cam.rect.y); } } public static Rect screenRect { get { return new Rect(cam.rect.x * Screen.width, cam.rect.y * Screen.height, cam.rect.width * Screen.width, cam.rect.height * Screen.height); } } public static Vector3 mousePosition { get { Vector3 mousePos = Input.mousePosition; mousePos.y -= (int)(cam.rect.y * Screen.height); mousePos.x -= (int)(cam.rect.x * Screen.width); return mousePos; } } public static Vector2 guiMousePosition { get { Vector2 mousePos = Event.current.mousePosition; mousePos.y = Mathf.Clamp(mousePos.y, cam.rect.y * Screen.height, cam.rect.y * Screen.height + cam.rect.height * Screen.height); mousePos.x = Mathf.Clamp(mousePos.x, cam.rect.x * Screen.width, cam.rect.x * Screen.width + cam.rect.width * Screen.width); return mousePos; } }}



AspectUtilityEnhanced.cs脚本:


csharp 代码
?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127using UnityEngine; public class AspectUtility : MonoBehaviour { public float _wantedAspectRatio = 1.5f; public bool landscapeModeOnly = true; static public bool _landscapeModeOnly = true; static float wantedAspectRatio; static Camera cam; static Camera backgroundCam; void Awake () { _landscapeModeOnly = landscapeModeOnly; cam = camera; if (!cam) { cam = Camera.main; Debug.Log ("Setting the main camera " + https://www.360docs.net/doc/7d7747804.html,); } else { Debug.Log ("Setting the main camera " + https://www.360docs.net/doc/7d7747804.html,); } if (!cam) { Debug.LogError ("No camera available"); return; } wantedAspectRatio = _wantedAspectRatio; SetCamera(); } public static void SetCamera () { float currentAspectRatio = 0.0f; if(Screen.orientation == https://www.360docs.net/doc/7d7747804.html,ndscapeRight || Screen.orientation == https://www.360docs.net/doc/7d7747804.html,ndscapeLeft) { Debug.Log ("Landscape detected..."); currentAspectRatio = (float)Screen.width / Screen.height; } else { Debug.Log ("Portrait detected...?"); if(Screen.height > Screen.width && _landscapeModeOnly) { currentAspectRatio = (float)Screen.height / Screen.width; } else { currentAspectRatio = (float)Screen.width / Screen.height; } } // If the current aspect ratio is already approximately equal to the desired aspect ratio, // use a full-screen Rect (in case it was set to something else previously) Debug.Log ("currentAspectRatio = " + currentAspectRa

tio + ", wantedAspectRatio = " + wantedAspectRatio); if ((int)(currentAspectRatio * 100) / 100.0f == (int)(wantedAspectRatio * 100) / 100.0f) { cam.rect = new Rect(0.0f, 0.0f, 1.0f, 1.0f); if (backgroundCam) { Destroy(backgroundCam.gameObject); } return; } // Pillarbox if (currentAspectRatio > wantedAspectRatio) { float inset = 1.0f - wantedAspectRatio/currentAspectRatio; cam.rect = new Rect(inset/2, 0.0f, 1.0f-inset, 1.0f); } // Letterbox else { float inset = 1.0f - currentAspectRatio/wantedAspectRatio; cam.rect = new Rect(0.0f, inset/2, 1.0f, 1.0f-inset); } if (!backgroundCam) { // Make a new camera behind the normal camera which displays black; otherwise the unused space is undefined backgroundCam = new GameObject("BackgroundCam", typeof(Camera)).camera; backgroundCam.depth = int.MinValue; backgroundCam.clearFlags = CameraClearFlags.SolidColor; backgroundCam.backgroundColor = Color.black; backgroundCam.cullingMask = 0; } } public static int screenHeight { get { return (int)(Screen.height * cam.rect.height); } } public static int screenWidth { get { return (int)(Screen.width * cam.rect.width); } } public static int xOffset { get { return (int)(Screen.width * cam.rect.x); } } public static int yOffset { get { return (int)(Screen.height * cam.rect.y); } } public static Rect screenRect { get { return new Rect(cam.rect.x * Screen.width, cam.rect.y * Screen.height, cam.rect.width * Screen.width, cam.rect.height * Screen.height); } } public static Vector3 mousePosition { get { Vector3 mousePos = Input.mousePosition; mousePos.y -= (int)(cam.rect.y * Screen.height); mousePos.x -= (int)(cam.rect.x * Screen.width); return mousePos; } } public static Vector2 guiMousePosition { get { Vector2 mousePos = Event.current.mousePosition; mousePos.y = Mathf.Clamp(mousePos.y, cam.rect.y * Screen.height, cam.rect.y * Screen.height + cam.rect.height * Screen.height); mousePos.x = Mathf.Clamp(mousePos.x, cam.rect.x * Screen.width, cam.rect.x * Screen.width + cam.rect.width * Screen.width); return mousePos; } }}



原文:https://www.360docs.net/doc/7d7747804.html,/index.php?title=AspectRatioEnforcer
译者:威阿,转载请注明来自https://www.360docs.net/doc/7d7747804.html,



Tags: UnityUnity guigui 游戏开发游戏开发 gui比例gui比例 屏幕屏幕 游戏屏幕游戏屏幕 界面界面
相关日志: 输出Unity的场景文件为Obj模型文件[465]
Unity CEO访谈:Unreal投机 Unity简单实在[678]
Unity 4.0正式发布!官网同步改版.[1477]
Unity 3.5.6发布

及更新说明[1473]
Unity3.5.5发布,更新列表.[2205]
Unity内建Package简要说明[2646]
在Unity编辑器上增加你自己的工具[2392]
Unity3.5.1版本更新修正列表[2518]
Unity3.5中内建精简字体字库方法讲解[5790]
久违的更新-Unity3.5正式版发布!(中文版更新说明)[8998]
分页: [1][2][3][4][5]
模式: 全部显示[共164个相关文章]评论: 0 | 引用: 0 | 查看次数: 1011
发表评论
昵 称:
密 码: 游客发言不需要密码.
内 容:

正在加载编辑器...

选 项:禁止表情转换 禁止自动转换链接 禁止自动转换关键字

虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.
字数限制 1000 字 | UBB代码 开启 | [img]标签 关闭
关于我Name:XiaoKe
Age:28
QQ:3122828
Tel:134****2989

Weibo:@Unity3(sina,qq,163)
Msn:VrMsn#https://www.360docs.net/doc/7d7747804.html,
Mail:MineVR#https://www.360docs.net/doc/7d7747804.html,
Unity引擎Unity QQ Group: 2453819,34643309,7838310
Unity Sina Group: 110440
Unity BaiduHi: 1049402
Unity Official IRC: Links
Unity Magazine: Links
Unity CN Froum: Links
Unity CN Answers: Links
Unity Wiki: Links
Unity Forum: Links
最新评论虽然很少在mac下看flash了,但还是很感谢你。...thx,不过发现与 ClickToFlash 这个...可用。
Thanks!我的装了没有用,我的RMBP15,10.8 只装...可以更改 https://www.360docs.net/doc/7d7747804.html,来实现
动态加载a...楼主,这是用什么语言做的?转换后,空间坐标怎么办?...2009的max早就把fbx插件集成了。还装什么插...请问用户想添加一张从网上刚下载的壁纸进行替换,,是...灰常感谢[Lovely]感谢!

最新留言威哥又要开始发威拉。
娃哈哈~~~“适当调节遮挡区栅格的密度.根据你游戏物体体积权衡...威大,我在试着做游戏优化,在遮挡剔除这部分,我把遮...我加QQ群,怎么没有通过啊博主你好,请问U3D里的把所有物体的线框显示出来是...谢谢啊,不过unity每次发布beta版本我都不知...您好,大神,能帮我看个flash导出的问题吗,当我...你好!刚刚看了你的教程,也在优酷上加了关注!希望能...博主威武!!!好厉害的说!!支持一个~~
...博主,偶然来到这里,我决定关注你了,你是我的,不,...用户面板登录用户注册统计日志: 616 篇
评论: 956 个
留言: 214 个
会员: 475 人
访问: 10387493 次
在线: 10 人
建站时间: 2004-08-26
日历2013年1月日一二三四五六30311234567891011121314151617181920212223242526272829303112
类别首页
生活琐事 [159]
日常工作 [80]
技术日志 [185]
我的成果 [92]
杂七杂八 [100]
访客留言
论坛
标签云集

存档201201月02月05月07月08月
10月11月12月201101月02月03月04月05月
06月07月09月10月201001月03月04月05月06月
07月09月10月11月12月
200901月02月03月04月05月
06月07月08月09月10


11月12月200801月02月03月05月06月
07月08月09月10月11月
12月200701月02月03月04月05月
06月07月08月09月10月
11月12月200601月02月03月07月08月
09月10月11月12月200501月02月03月04月05月
06月07月11月12月200411月12月
搜索关键字 类 型 日志标题 日志内容 日志评论 引用通告
支持


Powered By PJBlog CopyRight 2005 - 2008, XiaoKe's Blog xhtml | css | 网站统计 关闭提示
关闭确 认 取 消

相关主题
相关文档
最新文档