Unity开发过程中如何正确的拿到Screen的width和height
首先明确两个概念:
Screen.currentResolution - 指的是设备分辨率,比如:电脑上指的就是电脑的屏幕分辨率,手机上指的就是手机的屏幕分辨率。
Screen.width,Screen.height - 指的是使用该值的窗口的宽高,比如:在Scene窗口使用指的就是Scene窗口的宽高,在Game窗口使用,即运行编辑器时使用,指的就是Game窗口的宽高,在自定义的Window使用指的就是自定义的Window的宽高。
定义如下窗口,用来测试上述结论:
代码:
1 using UnityEngine; 2 using UnityEditor; 3 4 5 public class CustomWindow : EditorWindow 6 { 7 static CustomWindow mWin; 8 9 [MenuItem("自定义窗口/MyWin")] 10 static void ShowWin() 11 { 12 mWin = GetWindow<CustomWindow>(); 13 mWin.titleContent = new GUIContent("MyWin"); 14 mWin.minSize = new Vector2(400, 200); 15 } 16 17 void OnGUI() 18 { 19 if (GUILayout.Button("ShowInfo", GUILayout.Width(200), GUILayout.Height(50))) 20 { 21 Debug.Log("Screen.width = " + Screen.width + " Screen.height = " + Screen.height + " | currentResolution = " + Screen.currentResolution); 22 } 23 } 24 }
打印结果:
在游戏开发过程中,我们更多关注的是Game视图下的屏幕宽高。假如,我们想在自定的Window中获取Game视图的屏幕宽高,该如何做呢?
下面是NGUI-3.9.4中提供的获取Game视图屏幕宽高的方法:
1 static int mSizeFrame = -1; 2 static System.Reflection.MethodInfo s_GetSizeOfMainGameView; 3 static Vector2 mGameSize = Vector2.one; 4 5 /// <summary> 6 /// Size of the game view cannot be retrieved from Screen.width and Screen.height when the game view is hidden. 7 /// </summary> 8 9 static public Vector2 screenSize 10 { 11 get 12 { 13 int frame = Time.frameCount; 14 15 if (mSizeFrame != frame || !Application.isPlaying) 16 { 17 mSizeFrame = frame; 18 19 if (s_GetSizeOfMainGameView == null) 20 { 21 System.Type type = System.Type.GetType("UnityEditor.GameView,UnityEditor"); 22 s_GetSizeOfMainGameView = type.GetMethod("GetSizeOfMainGameView", 23 System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); 24 } 25 mGameSize = (Vector2)s_GetSizeOfMainGameView.Invoke(null, null); 26 } 27 return mGameSize; 28 } 29 }
对于移动设备,个人理解Screen.width,Screen.height和Screen.currentResolution值是一样的(并未实际验证)。为了安全起见,个人建议,编辑器下和移动设备上最好用Screen.width,Screen.height统一起来。NGUI也是这个思路:
1 #if UNITY_EDITOR 2 static int mSizeFrame = -1; 3 static System.Reflection.MethodInfo s_GetSizeOfMainGameView; 4 static Vector2 mGameSize = Vector2.one; 5 6 /// <summary> 7 /// Size of the game view cannot be retrieved from Screen.width and Screen.height when the game view is hidden. 8 /// </summary> 9 10 static public Vector2 screenSize 11 { 12 get 13 { 14 int frame = Time.frameCount; 15 16 if (mSizeFrame != frame || !Application.isPlaying) 17 { 18 mSizeFrame = frame; 19 20 if (s_GetSizeOfMainGameView == null) 21 { 22 System.Type type = System.Type.GetType("UnityEditor.GameView,UnityEditor"); 23 s_GetSizeOfMainGameView = type.GetMethod("GetSizeOfMainGameView", 24 System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); 25 } 26 mGameSize = (Vector2)s_GetSizeOfMainGameView.Invoke(null, null); 27 } 28 return mGameSize; 29 } 30 } 31 #else 32 /// <summary> 33 /// Size of the game view cannot be retrieved from Screen.width and Screen.height when the game view is hidden. 34 /// </summary> 35 36 static public Vector2 screenSize { get { return new Vector2(Screen.width, Screen.height); } } 37 #endif
这里再提供一个折叠屏手机展开或者闭合后屏幕适配的一个思路:
Update中检测Screen的size是否发生变化,如果发生变化就去刷新一下锚定设置。
代码:
1 using UnityEngine; 2 3 public class CheckScreen : MonoBehaviour 4 { 5 int screenWidth, screenHeight; 6 void Start() 7 { 8 screenWidth = Screen.width; 9 screenHeight = Screen.height; 10 } 11 12 13 void Update() 14 { 15 if (screenWidth != Screen.width || screenHeight != Screen.height) 16 { 17 screenWidth = Screen.width; 18 screenHeight = Screen.height; 19 OnScreenChange(); 20 } 21 } 22 23 void OnScreenChange() 24 { 25 //发送消息-处理适配之 前 的一些操作 26 //UI适配 27 //3D适配 28 //其他... 29 //发送消息-处理适配之 后 的一些操作 30 } 31 }