我们知道尽量少在MonoBehaviour脚本的Update回调中处理逻辑,对游戏性能影响比较大。但是有些逻辑又必须写在Update中,比如游戏AI模块,或子系统更新等。更糟糕的是,如果又要求当前场景中有成千上万的NPC敌人在场时,如果每个NPC都有Update回调都执行的话,而且它们极有可能在同一帧触发,这会产生一个巨大的CPU使用峰值。Unity调用Update时,会经历本机-托管桥接,而这是非常耗性能的。换句话来讲,执行10000个Update()回调要比在执行1个Update回调但执行10000个“OnUpdate”函数成本要高很多。后者另外也为我们能更好地控制更新提供了操作空间。比如:如果发现即将达到当前帧的CPU预算时,可以把某些低优先级的任务暂停下来。
脚本如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/*
* Author:W
* 更新接口
*/
public class IUpdate: MonoBehaviour{
public virtual void OnUpdate() { }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/*
* Author:W
* 活动系统
*/
public class ActivitySystem : IUpdate {
public override void OnUpdate() { }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/*
* Author:W
* 任务成就系统
*/
public class AcheiveSystem :IUpdate {
public override void OnUpdate() { }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/*
* Author:W
* 游戏更新检测控制脚本
*/
public class Game : MonoBehaviour {
private List<IUpdate> systemList = new List<IUpdate>();
/// <summary>
/// 注册
/// </summary>
/// <param name="updateSys"></param>
public void RegisterSystem(IUpdate updateSys)
{
if (!systemList.Contains(updateSys))
systemList.Add(updateSys);
}
/// <summary>
/// 注销
/// </summary>
/// <param name="updateSys"></param>
public void UnRegisterSystem(IUpdate updateSys)
{
if (systemList.Contains(updateSys))
systemList.Remove(updateSys);
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
for (int i = 0; i < systemList.Count; i++)
{
systemList[i].OnUpdate();
}
}
}