程序集引用¶
为什么要分程序集? 编辑器程序不应该在打包时引用进去,所以我们使用将编辑器程序全部封在GameCoreEditor下面。明确依赖关系,GameEditor可以引用GameCore,而反之则不能。因为游戏包体不能因为没有编译Editor相关文件而发生错误。
编辑器数据获得¶
由于GameCore不能直接给编辑器的类型赋值,所以我们必须采用事件注册和回调的方式来获取数据。 我们在GameCore中设置一个管理BulletEditorManager类,提供事件注册。
-
GameCore.BulletEditorManager
public static event System.Action<BulletDeadInfo> bulletDebugInfoChangeCallback; //DeadInfo是自己定义的数据类 public void SendBulletDebugEvent(BulletDeadInfo bulletDeadInfo) { bulletDebugInfoChangeCallback?.Invoke(bulletDeadInfo); } public void SendBulletDeadEvent(Bullet bullet) { SendBulletDebugEvent(new BulletDeadInfo(bullet)); }
-
GameCore.Bullet
protected virtual void OnDead() { #if UNITY_EDITOR DamageDebuggerManager.Instance?.SendBulletDeadEvent(this) #endif ... }
这里补充个优化,由于我们要实时监控子弹,而每个子弹的销毁都要new一个info对象,会加大GC的负担,所以我们直接传bullet就行了
-
GameCore.BulletEditorManager
#region 子弹监控工具 //子弹监控工具使用(其实根本就不需要那么多东西,避免创建新对象直接传Bullet) public static event System.Action<Bullet> bulletDebugInfoChangeCallback; public void SendBulletDeadEvent(Bullet deadBullet) { bulletDebugInfoChangeCallback?.Invoke(deadBullet); } #endregion
-
GameCore.
而GameCoreEditor中,我们只需要把方法注册进去,就可以对函数进行监控了 + GameCoreEditor.BulletMonitorWindow
void OnEnable()
{
//检查是否已存在序列化视图状态(在程序集重新加载后
// 仍然存在的状态)
if (m_TreeViewState == null)
m_TreeViewState = new TreeViewState();
m_TreeView = new BulletAnalyzeTreeView(m_TreeViewState);
//事件监听
DamageDebuggerManager.bulletDebugInfoChangeCallback += BulletDebugInfoNewAddCallback;
}
public void OnDisable()
{
DamageDebuggerManager.bulletDebugInfoChangeCallback -= BulletDebugInfoNewAddCallback;
}
//信息处理
private void BulletDebugInfoNewAddCallback(BulletDeadInfo info)
{
m_TreeView.RefreshDeadInfo(info.instanceID, info.deadType);
}
预处理宏¶
对于这些Editor在GameCore中处理的逻辑,按理来说也是没有必要在打包后使用的,我们使用宏让打包后的游戏进行预处理,从而不参与编译过程。
#if UNITY_EDITOR
public class DamageDebuggerManager
{
#if UNITY_EDITOR
...
#endif
}