帧事件管理器

转载自:http://www.omuying.com/article/126.aspx

大家在开发 Unity 的时候,肯定使用过 MonoBehaviour 中的 Update 函数,在每个类中调用 Update 有很多优点,当然也有非常多的缺点,下面我们说说他的优点与缺点。

优点部分(不完全)

1、方便,每个逻辑单独处理,比如每个子弹对象控制每个子弹的移动轨迹等等。

缺点部分(不完全)

1、每个类的 Update 函数都会自动运行,禁止自动运行一是禁用脚本,但是禁用脚本之后,其他的固定执行函数将无法继续进行,二是添加状态判断,这样又会增加每个类的执行效率开销。
2、每个类的 Update 执行顺序不能统一,比如一个子弹每帧移动 5 像素,另一个子弹每帧移动 5 像素,但是不能保证他们能在同帧中同时到达目标位置。
3、暂停比较麻烦,比如我们希望场景中的某些角色停止一分钟,这个时候我们最常用的就是添加一个状态,然后在 Update 中判断这个状态值,但是这样会增加每个类的执行效率开销。

因为以前在开发 FLASH 游戏的时候,会经常使用帧管理器来统一管理游戏的运行,因为这样可以保证游戏对象都有统一的节奏,在一个帧中可能执行的逻辑有些复杂,但是这会确保游戏对象都有统一的时间延迟,根据以前的经验,用 Unity 实现了一个帧管理器,这样做的好处是只需要几个少数的 Update 函数就可以管理游戏中所有的对象节奏,保证逻辑统一,并且有序。

主要的类只有两个,一个是 FrameItem.cs 类,代码如下:
using UnityEngine;
using System;

/// <summary>
/// 帧对象,任何调用 Update 的类都应该交由 FrameItem 管理
/// </summary>
public class FrameItem 
{
	private Action callback;

	/// <summary>
	/// 构造函数,必须实例化
	/// </summary>
	/// <param name="callback">Callback.</param>
	public FrameItem(Action callback)
	{
		this.callback = callback;
	}

	/// <summary>
	/// 帧管理器
	/// </summary>
	/// <param name="callback">Callback.</param>
	public virtual void FrameUpdate()
	{
		this.callback();
	}
}
另一个是 FrameManager 类,代码如下:
using UnityEngine;
using System;
using System.Collections.Generic;

/// <summary>
/// 帧管理器
/// </summary>
public class FrameManager
{
	public static Dictionary<object, FrameItem> frameList = new Dictionary<object, FrameItem>();

	/// <summary>
	/// 调用函数
	/// </summary>
	public static void Run()
	{
		FrameItem[] objectList = new FrameItem[frameList.Values.Count];
		frameList.Values.CopyTo(objectList, 0);
		
		// 锁定
		foreach(FrameItem frameItem in objectList)
		{
			if(frameItem != null) frameItem.FrameUpdate();
		}
	}

	/// <summary>
	/// 注册帧管理器
	/// </summary>
	/// <param name="objectItem">Object item.</param>
	/// <param name="callback">Callback.</param>
	public static void Register(object objectItem, Action callback = null)
	{
		if(!frameList.ContainsKey(objectItem))
		{
			FrameItem frameItem = new FrameItem(callback);
			frameList.Add(objectItem, frameItem);
		}
	}

	/// <summary>
	/// 取消注册帧管理器
	/// </summary>
	/// <param name="objectItem">Object item.</param>
	public static void UnRegister(object objectItem)
	{
		if(frameList.ContainsKey(objectItem)) frameList.Remove(objectItem);
	}
}
测试用例的代码如下(完整代码可以下载源代码运行):
using UnityEngine;
using System.Collections;

public class DemoItem : MonoBehaviour 
{
	public int index;

	public void Init()
	{
		FrameManager.Register(this, this.UpdateCallback);
	}

	private void UpdateCallback()
	{
		// 处理一些事情等同于 Update
	}
}
全局代码
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Demo : MonoBehaviour 
{
	private List<DemoItem> itemList;

	void Awake()
	{
		this.itemList = new List<DemoItem> ();

		GameObject objectItem = null;
		DemoItem demoItem = null;

		for(int index = 0; index < 500; index ++)
		{
			objectItem = new GameObject();
			objectItem.name = "item_" + index;
			demoItem = objectItem.AddComponent<DemoItem>();
			demoItem.index = index;

			this.itemList.Add(demoItem);
		}

		this.StartCoroutine (this.AwakeEnumerator());
	}

	private IEnumerator AwakeEnumerator()
	{
		yield return new WaitForSeconds (5f);

		int length = this.itemList.Count;
		for(int index = 0; index < length; index ++)
		{
			this.itemList[index].Init();
		}
	}

	void Update()
	{
		FrameManager.Run ();
	}
}

/*
 * Unity3D 帧事件管理器(关于 MonoBehaviour 的 Update 函数)
 * 大家在开发 Unity 的时候,肯定使用过 MonoBehaviour 中的 Update 函数,在每个类中调用 Update 有很多优点,当然也有非常多的缺点,下面我们说说他的优点与缺点。
 * 优点部分(不完全)
 * 1、方便,每个逻辑单独处理,比如每个子弹对象控制每个子弹的移动轨迹等等。
 * 缺点部分(不完全)
 * 1、每个类的 Update 函数都会自动运行,禁止自动运行一是禁用脚本,但是禁用脚本之后,其他的固定执行函数将无法继续进行,二是添加状态判断,这样又会增加每个类的执行效率开销。
 * 2、每个类的 Update 执行顺序不能统一,比如一个子弹每帧移动 5 像素,另一个子弹每帧移动 5 像素,但是不能保证他们能在同帧中同时到达目标位置。
 * 3、暂停比较麻烦,比如我们希望场景中的某些角色停止一分钟,这个时候我们最常用的就是添加一个状态,然后在 Update 中判断这个状态值,但是这样会增加每个类的执行效率开销。
 * 
 * 因为以前在开发 FLASH 游戏的时候,会经常使用帧管理器来统一管理游戏的运行,因为这样可以保证游戏对象都有统一的节奏,在一个帧中可能执行的逻辑有些复杂,但是这会确保游戏对象都有统一的时间延迟,根据以前的经验,用 Unity 实现了一个帧管理器,这样做的好处是只需要几个少数的 Update 函数就可以管理游戏中所有的对象节奏,保证逻辑统一,并且有序。
 * 
 * 主要的类只有两个,一个是 FrameItem.cs 类,代码如下:
 * 另一个是 FrameManager 类,代码如下:
 * 
 * 测试用例的代码如下(完整代码可以下载源代码运行):
 * 
 * 最后我们只有一个 Update 函数,就是 Demo.cs 中的 Update 函数,这个函数控制着场景中创建的 500 个对象的 Update 函数,通过 FrameManager 类,我们可以非常容易控制某些对象暂停执行 Update,并且不会额降低代码执行的效率。
 * */

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值