纳金网
标题: Unity3D自适应屏幕方案 [打印本页]
作者: 狂风大尉 时间: 2015-9-30 23:24
标题: Unity3D自适应屏幕方案
如果做手机游戏,必不可少的需要涉及到自适应屏幕这个问题,本篇文章不做过多讲解。直接上代码。
AspectUtility.cs脚本来自网络,因考虑到宽屏和窄屏适应问题,设置一个可调节的区间段会比较好,所以此处做过部分修改。
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- public class AspectUtility : MonoBehaviour
- {
- public Vector2 maxAspectRatio = new Vector2(16, 9);
- public Vector2 minAspectRatio = new Vector2(3, 2);
- public bool landscapeModeOnly = true;
- private float _wantedAspectRatio = 1.5f;
- static public bool _landscapeModeOnly = true;
- static float wantedAspectRatio;
- static Camera cam;
- static Camera backgroundCam;
- void Awake()
- {
- if (Screen.width * maxAspectRatio.y > Screen.height * maxAspectRatio.x)
- {
- _wantedAspectRatio = maxAspectRatio.x / maxAspectRatio.y;
- }
- else if (Screen.width * minAspectRatio.y < Screen.height * minAspectRatio.x)
- {
- _wantedAspectRatio = minAspectRatio.x / minAspectRatio.y;
- }
- else
- {
- _wantedAspectRatio = (float)Screen.width / Screen.height;
- }
- _landscapeModeOnly = landscapeModeOnly;
- cam = camera;
- if (!cam)
- {
- cam = Camera.main;
- Debug.Log("Setting the main camera " + cam.name);
- }
- else
- {
- Debug.Log("Setting the main camera " + cam.name);
- }
- if (!cam)
- {
- Debug.LogError("No camera available");
- return;
- }
- wantedAspectRatio = _wantedAspectRatio;
- SetCamera();
- }
- public static void SetCamera()
- {
- float currentAspectRatio = 0.0f;
- if (Screen.orientation == ScreenOrientation.LandscapeRight ||
- Screen.orientation == ScreenOrientation.LandscapeLeft)
- {
- 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 = " + currentAspectRatio + ", 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;
- }
- }
- }
复制代码原文:http://wiki.unity3d.com/index.php?title=AspectRatioEnforcer
以上脚本可以实现3D场景的自适应,如果采用NGUI布局UI界面,只需要再进行以下处理即可:
- UIRoot root = _uiCamera2D.transform.parent.GetComponent<UIRoot>();
- int height;
- if (AspectUtility.screenWidth * UIConfig.instance.uiSize.y > AspectUtility.screenHeight * UIConfig.instance.uiSize.x)
- {
- height = (int)UIConfig.instance.uiSize.y;
- if (root != null)
- {
- root.maximumHeight = height;
- root.minimumHeight = height;
- }
- }
- else
- {
- height = (int)(AspectUtility.screenHeight * UIConfig.instance.uiSize.x / AspectUtility.screenWidth);
- if (root != null)
- {
- root.minimumHeight = height;
- root.maximumHeight = height;
- }
- }
复制代码 其中的_uiCamera2D自然就是NGUI的2D照相机了
欢迎光临 纳金网 (http://rs.narkii.com/club/) |
Powered by Discuz! X2.5 |