Unity切后台pixelWidth和pixelHeight发生了变化
发表于2017-10-25
一、
上周遇到一个bug,游戏手机上切后台然后在切回来的时候屏幕会变成白色。 在Editor下我关闭了RunGround。试了一下并未发现任何异常。我猜想要么是后处理有问题,要么是修改了什么参数导致unity释放了某些资源导致。通过查看关于后处理的代码并未发现异常。于是我决定在手机端截帧查看一下。 立即下载了一个高通的Snapdragon Profiler。之前的那个Adreno Profiler是旧版了。另外我的用的测试机是小米,使用了高通的处理器,所以可以用高通的工具来截帧。
工具下载之后,安装好apk,启动。然后在出现异常的时候截取了一帧的数据。 发现在渲染完所有场景的物体之后便出现了白屏。可以断定的是场景的Camera渲染出来的东西有问题。
二、
回到项目中,查看Carema以及后处理的代码。我们项目中大概的做法是MainCamera渲染到一张大小和像素一样大小的RenderTexture上,然后在进行后处理。不过有个奇怪的地方就是会不断检测Camera的pixelWidth和pixelHeight,如果一旦发生改变就立刻重新创建RenderTexture。我试着在编辑器下把屏幕窗口模式改成Free Aspect,当我改变窗口大小的是时候,立刻就出现了和手机上相同的问题:整个场景都是白色的了。于是可以断定是后处理这里出了问题。
三、
但我还需要进一步验证一下在手机上前后台切换的时候会修改pixelWidth和pixelHeight。另外开了一个Unity的小工程,添加一个脚本:
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Text; [RequireComponent(typeof(Camera))] public class MainCameraHandler : MonoBehaviour { public UnityEngine.UI.Text m_Text; Camera m_Cam; int m_Width = 0; int m_Height = 0; int m_ScreenWidth; int m_ScreenHeight; List<string> m_LogList = new List<string>(); // Use this for initialization void Start () { m_Cam = GetComponent<Camera> (); m_Width = m_Cam.pixelWidth; m_Height = m_Cam.pixelHeight; ShowLog(string.Format ("Start Camera = {0} pixelWidth:{1} pixelHeight:{2}", m_Cam.name, m_Width, m_Height)); m_ScreenHeight = Screen.height; m_ScreenWidth = Screen.width; ShowLog(string.Format ("Start Screen pixelWidth:{0} pixelHeight:{1}",m_ScreenWidth, m_ScreenHeight)); } // Update is called once per frame void Update () { if (m_Cam.pixelWidth != m_Width || m_Cam.pixelHeight != m_Height) { m_Width = m_Cam.pixelWidth; m_Height = m_Cam.pixelHeight; ShowLog(string.Format ("Update Camera = {0} pixelWidth:{1} pixelHeight:{2}", m_Cam.name, m_Width, m_Height)); } if (m_ScreenHeight != Screen.height || m_ScreenWidth != Screen.width) { m_ScreenHeight = Screen.height; m_ScreenWidth = Screen.width; ShowLog(string.Format ("Update Screen pixelWidth:{0} pixelHeight:{1}",m_ScreenWidth, m_ScreenHeight)); } } void OnApplicationPause(bool paused) { ShowLog ("OnApplicationPause = " paused); } void ShowLog(string msg) { int frame = Time.frameCount; string msg_str = string.Format ("[{0}]: {1}", frame, msg); Debug.LogError (msg_str); if (m_LogList.Count > 10) { m_LogList.RemoveAt (0); } m_LogList.Add (msg_str); if (m_Text != null) { StringBuilder sb = new StringBuilder (); foreach (var s in m_LogList) { sb.Append (s).Append ("\n"); } m_Text.text = sb.ToString (); } } }
然后把整个组件添加到MainCamera当中,另外在添加一个Text用于显示日志。 切换到android平台,打包,运行到手机上。
当我切换到后台在切回到app时,Camera的pixelWidth和pixelHeight发生了两次变化。而且刚好是pixelWidth 和 pixelHeight 发生了对调。 因此可能是app首先切换成竖屏然后在切换成横屏。
四、
回到项目当中,因此则修改后处理的代码,当发生了RenderTexture的变化的时候,也需要重新设置一下CommandBuffer。