某些游戏项目关卡地图场景很大,而对于玩家而言,他的可视区域只是场景地图一小部分。而那些非可视区域的游戏对象还是还一直在“后台”执行游戏逻辑中,其实是没必要的,而且会对性能造成很大影响。Unity引擎在渲染层面已经做了一些优化:
(1)自动对相机视图不可见的游戏对象避免去渲染,称之为“视锥剔除”技术;
(2)自动避免渲染隐藏在其他对象后面的对象,称之为“遮挡剔除”技术;
但是,它不会影响在CPU上执行任务的脚本组件,比如:AI脚本、UI界面和其他的游戏逻辑。这些必须由我们自己手动来控制。
因此,这里列举2种策略来禁用开启游戏对象或组件。
其一,通过可见性禁用对象。对于场景中一个游戏对象,当所有的相机都不可见时,会触发OnBecameVisible();当场景中任何一个相机可见时,就会触发OnBecameInvisible()的回调。
【注意】由于可见性回调与渲染管线通信,因此,GameObject游戏对象必须附加上MeshRenderer后SkinnedMeshRenderer组件。
测试脚本如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/*
 * Author:W
 * 性能优化:场景中游戏对象的可见与否的回调
 * 1.OnBecameVisible
 * 2.OnBecameInVisible
 */
public class OnBecameVisibleTest : MonoBehaviour {
    /// <summary>
    /// 游戏对象可见时
    /// </summary>
    void OnBecameVisible()
    {
        Debug.Log("====游戏对象可见时======");
        this.enabled = true; 
        
    }

    /// <summary>
    /// 游戏对象不可见时
    /// </summary>
    void OnBecameInvisible()
    {
        Debug.Log("====游戏对象不可见时======");
        this.enabled = false;        
    }
}

结果如下截图:通过拉动胶囊体对象的远近。

unity 禁用 resourcemanager 内存 unity 禁用脚本_System


其二,通过距离玩家的远近禁用对象。当玩家离游戏对象足够远时,以至于几乎看不到它们,另外,玩家也不要关注到它们时,此时可以考虑禁用它们。

测试脚本如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/*
 * Author:W
 * 通过与玩家的距离来禁用对象
 */
public class DistanceVisibleTest : MonoBehaviour {

	/// <summary>
	/// 玩家
	/// </summary>
	public GameObject player;
	/// <summary>
	/// 距离玩家的最大距离
	/// </summary>
	public float maxDis;
	/// <summary>
	/// 检测频率
	/// </summary>
	public int frameDelay;

	// Use this for initialization
	void Start () {
		//开启距离检测
		StartCoroutine(CheckToPlayerDistance());
	}

	IEnumerator CheckToPlayerDistance()
	{
		while (true)
		{
			float disSqrd = (this.transform.position - player.transform.position).sqrMagnitude;
			//距离玩家小于最大距离时,开启
			if (disSqrd < maxDis * maxDis)
			{
				this.enabled = true;
				Debug.Log("======开启=======");
			}
			else
			{
				this.enabled = false;
				Debug.Log("======关闭=======");
			}

			//设置调用协程的频率
			for (int i = 0; i < frameDelay; i++)
			{
				yield return new WaitForEndOfFrame();
			}
		}
	}
		
}

结果如图

unity 禁用 resourcemanager 内存 unity 禁用脚本_性能优化_02


总结:上面讲述了2种禁用开启游戏对象策略,读者可以根据自己的项目特点来选择。