ngui打包pc端后报错,在editor中是正常的。具体错误如下:
定位UIDrawCall脚本处,应该是调用unity3d的api,获得transform报错的。
public Transform cachedTransform { get { if (mTrans == null) mTrans = transform; return mTrans; } }
。也就是说drawcall对象删除了。表示很费解,看代码,明明drawCall脚本绑定的对象都是设置了dontdestory。(注:可以打开UIDrawCall脚本顶部的宏,#define SHOW_HIDDEN_OBJECTS 来查看drawcall对象)。然后google后看到一个大大写的:
/// 卸载场景
public void UnloadScene (string sceneName)
{
Scene scene = SceneManager.GetSceneByName ("Main");
SceneManager.SetActiveScene (scene);
// move existing draw calls to new active scene
// Solve BUG --- NullReferenceException UIDrawCall.get_cachedTransform
// 用到NGUI才需要下面的代码:
/*
foreach(var dc in UIDrawCall.activeList)
{
SceneManager.MoveGameObjectToScene(dc.gameObject, scene);
}
foreach (var dc in UIDrawCall.inactiveList)
{
SceneManager.MoveGameObjectToScene(dc.gameObject, scene);
}
*/
SceneManager.UnloadSceneAsync (sceneName);
}
看看注释的部分。可以了解到,切换场景时,有可能drawcall对象随着当前的场景删除被删除了。故,需要在加载完毕切换场景后,将drawcall对象移动到当前场景,在卸载上一场景,即可。公司项目,切换场景的逻辑是,先unload在切换新场景,且如上发现ngui 的drawcall对象在非editor下是DontDestroyed:
#if UNITY_EDITOR
// If we're in the editor, create the game object with hide flags set right away
GameObject go = UnityEditor.EditorUtility.CreateGameObjectWithHideFlags(name,
#if SHOW_HIDDEN_OBJECTS
HideFlags.DontSave | HideFlags.NotEditable, typeof(UIDrawCall));
#else
HideFlags.HideAndDontSave, typeof(UIDrawCall));
#endif
UIDrawCall newDC = go.GetComponent<UIDrawCall>();
#else
GameObject go = new GameObject(name);
DontDestroyOnLoad(go);
UIDrawCall newDC = go.AddComponent<UIDrawCall>();
#endif
// Create the draw call
mActiveList.Add(newDC);
return newDC;
所以不可能是这个原因。打包输出日志发现,unload时:
Unloading the last scene Assets/ExportRes/Scenes/xxx_editor.unity(build index: 22), is not supported. Please use SceneManager.LoadScene()/EditorSceneManager.OpenScene() to switch to another scene.
抱着试一试的心态,把所有的SceneManager.UnloadScene()去掉了,发现null错误就没了。估计是5.4.3版本下,切换时除了是增量的前提,会自动卸载之前加载的场景。反倒是,手动调用unloadScene会出问题...真是蛋疼。
相关:http://huijian.coding.me/2016/11/18/unity3d_develop_note/