IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]Unity的优化系列4 - 最好使用Canvas Overlay代替Screen Space Camera

    u010019717发表于 2016-06-01 08:56:00
    love 0

    孙广东  2016.5.23


    计算机生成了可选文字:


    Unity提供了用于创建 UI 的画布。画布上有渲染模式如下 ︰

    • 屏幕空间相机 Screen Space Camera
    • 屏幕空间覆盖 Screen Space Overlay
    • 世界空间 World Space

             让我们了解哪种模式是更好的,让我们以一个非常简单的示例测试这三项。


    1   屏幕空间相机


    让我们创建一个Unity项目︰

    脚本 ︰ MoveCamera.cs

    1. 在你的场景建立一个Canvas。
    2.  设置渲染模式为:  Screen Space Camera
    3. 将Main Camera,拖到render camera 选项(其他相机也可以)。
    4. 用sprite或图像中作为一个背景。
    5. 才Canvas内创建尽可能多的panels 和 UI的Texts 和Images
    6. 添加到Camera上的脚本。


    using UnityEngine; 
    using System.Collections;
    
    public class MoveCamera : MonoBehaviour
    {
    	private float velocity = 0.0f;
    	private float smoothTime = 0.3f;
    	private bool moveCamera = false;
    
    	public Vector3 initialPosition;
    	public Vector3 targetPosition;
    	public float lerpSpeed;
    
    	public float initialZ;
    	public float targetZ;
    	public Camera cam;
    	void Update ()
    	{
    		if (Input.GetMouseButtonDown (0)) {
    			initialPosition = transform.position;
    			targetPosition = new Vector3 (transform.position.x + Random.Range (-5, 5), transform.position.y + 				Random.Range (-5, 5), transform.position.z);
    			initialZ = transform.eulerAngles.z;
    			targetZ = initialZ + Random.Range (-50, 50);
    			moveCamera = true;
    			lerpSpeed = 0;
    		}
    		if (moveCamera) {
    			CameraMovementMethod ();
    		}
    	}
    
    	private void CameraMovementMethod ()
    	{
    		lerpSpeed = Mathf.SmoothDamp (lerpSpeed, 1.0f, ref velocity, smoothTime);
    		cam.transform.position = Vector3.Lerp (initialPosition, targetPosition, lerpSpeed);
    		cam.transform.eulerAngles = new Vector3 (0, 0, Mathf.LerpAngle (initialZ, targetZ, lerpSpeed));
    	}
    }
    

    1. Build部署到 Android 手机、 创建debugging build ,允许自动连接到profiler
    2.  在手机上运行该项目的,然后在处理随便点击屏幕
    3. 在Unity编辑器中profiler上搜索 "canvas",你会看到。:


    计算机生成了可选文字:
cpu usage 
Time m. 
select Line


     正如你从图片中可以看到,有很多的画布的调用Calls,特别注意到CanvasRender.OnTransformChanged

    每当相机移动,大约每个帧上有 50 次调用。

    注意   调用次数是依赖于Canvas上的 使用的UI 元素个数。

    我们可以更好地理解这与下面 gif:


    screen-space-camera-gif


    你可以看到上面,在游戏中移动Canvas相关的摄像机,因此每个UI 元素在画布上不得不由Unity引擎重新定位。因此越多的UI元素,就需要更多的处理。


    那么,解决方案是什么?


    2   屏幕空间覆盖


    在刚刚的测试项目中我们把 Canvas的渲染模式改为 Screen Space Overlay ,并重复之前的步骤,同样想在观察Profiler。

    大约我们优化它约 90%


    正如你可以看到以上,UI 画布保持原样在Unity空间,摄像机运动的不影响 UI Canvas根本。画布保持静态。


    因此,不需要任何重新定位或所需的处理。


    实现了高的优化。


    3   世界空间


    在世界空间模式,画布渲染手动更改为 World Space,测试结果和第一种一样。

    结论 ︰


    考虑screen space camera 类型的呈现进行大量的调用,所以非常推荐使用Overlay 绘制画布,使你的游戏在移动设备上更顺畅。(当然了这种只是限于纯UI),但是另外两种模式是有其特殊用处的!


    ForEach 循环优化


    计算机生成了可选文字:


    这是个老生常谈的话题, 主要还是产生GC的问题:


    public class ForEachLoopTest : MonoBehaviour
    { 
        #region PUBLIC_DECLARATIONS
        public List<GameObject> emptyGameObjects;
        #endregion
    
        #region UNITY_CALLBACKS
        void Update()
        {
            if (Input.GetKey(KeyCode.Space))
            {
                UpdateTextValue();
            }
        }
        #endregion
        #region PUBLIC_METHODS
        public void UpdateTextValue()
        {
            foreach (var item in emptyGameObjects)
            {
                // PROCESS ITEMS IN LIST
            }
    //        for (int i = 0; i < emptyGameObjects .Count; i++)
    //        {
            // PROCESS ITEMS IN LIST
    //        }
        }
        #endregion
    }

    Profiler ForEach Loop


    按下空格键 ,当是10~30大小的循环时  会看到如上图的 效果: 每帧产生 40B 的GC


    foreach (SomeType sin someList)

        s.DoSomething();


    现在编译, 编译器预处理的代码:


    using (SomeType.Enumerator enumerator = this.someList.GetEnumerator())
    
    {
    
        while (enumerator.MoveNext())
    
        {
    
            SomeType s = (SomeType)enumerator.Current;
    
            s.DoSomething();
    
        }
    
    }
    


    在每次迭代时,会创建一个 enumerator对象。





沪ICP备19023445号-2号
友情链接