ngui界面跳转不消失

2015年01月16日 13:03 0 点赞 0 评论 更新于 2025-11-21 14:33

在游戏开发中,有时需要实现NGUI界面在场景跳转时不消失,即对多个界面进行有效管理。下面将详细介绍实现这一功能的具体过程。

主要实现思路

将所有的界面都放置在场景A中。游戏启动时,首先加载场景A。所有的界面(UIRoot)都位于同一个游戏对象下,我们将这个游戏对象命名为 AllUIGameObject。在代码里使用 DontDestroyOnLoad(AllUIGameObject) 方法,这样在切换到其他场景(如场景B、C、D)时,界面能够继续存在。

当返回场景A时(例如切换账号回到登录界面的情况),由于需要重新开始登录流程,上一个账号的很多数据已经无效,因此需要销毁之前的 AllUIGameObject 对象。如果有一些角色数据使用了 static 或者单例等方式保存下来,还需要动态地进行重置。之后,再重新按照上述步骤加载场景A并执行相同的流程,这里的流程简单来说就是 LaunchGame.cs 脚本中的 Start() 函数。

在最初尝试使用 DestroyOnLoad(Obj) 方法时,来回切换 Obj 所在的场景会出现多份 Obj 的克隆。在网上搜索到的一些方法,如使用标志位判断是否已经克隆,或者用单例判断 Obj 是否已经被初始化过,都无法避免重复 Obj 的情况。因此,最终采用了上述的实现思路。

代码实现

LaunchGame.cs

using UnityEngine;

public class LaunchGame : MonoBehaviour
{
public GameObject mAllUIGameObject = null;
private static LaunchGame mInstance = null;

public static LaunchGame Instance
{
get
{
return mInstance;
}
private set
{
// 空实现,保留用于后续可能的扩展
}
}

void Start()
{
if (mInstance == null)
{
Debug.Log("LaunchGame.Start(), mInstance == null");
mInstance = this;
}

DontDestroyOnLoad(mAllUIGameObject);
UIManager.Instance.Init();
Debug.Log("LaunchGame.Start()");
}

void Update()
{
// 空实现,可根据需求添加逻辑
}

public void DestroyAllUIGameObject()
{
Destroy(mAllUIGameObject);
}
}

UIManager.cs

using System.Collections.Generic;

// 面板类型
public enum UIType
{
UI1,
UI2,
UI3,
UI4
}

// 界面逻辑管理器
public class UIManager : Singleton<UIManager>
{
public UI1 ui1 = null;
public UI2 ui2 = null;
public UI3 ui3 = null;
public UI4 ui4 = null;

Dictionary<UIType, UIBase> mUIDic = new Dictionary<UIType, UIBase>();

// 初始化界面逻辑
public void Init()
{
CheckMembers();
InitAllPanel();
}

// 检测成员变量是否有效
void CheckMembers()
{
Debug.Assert(ui1 != null, "UIManager.CheckMembers(), ui1 is null object!");
Debug.Assert(ui2 != null, "UIManager.CheckMembers(), ui2 is null object!");
Debug.Assert(ui3 != null, "UIManager.CheckMembers(), ui3 is null object!");
Debug.Assert(ui4 != null, "UIManager.CheckMembers(), ui4 is null object!");
}

// 初始化所有面板
void InitAllPanel()
{
mUIDic.Add(UIType.UI1, ui1);
mUIDic.Add(UIType.UI2, ui2);
mUIDic.Add(UIType.UI3, ui3);
mUIDic.Add(UIType.UI4, ui4);

foreach (UIBase ui in mUIDic.Values)
{
if (ui.m_panel != null)
{
ui.CheckWidget();
ui.Init();
ui.BindingEvent();
ui.Reset();
}
}
}

// 显示指定面板
public void ShowPanel(UIType type)
{
foreach (KeyValuePair<UIType, UIBase> item in mUIDic)
{
if (type == item.Key)
{
item.Value.Show();
}
else
{
item.Value.Hide();
}
}
}
}

场景切换说明

其他脚本(如 UI1UI2UI3UI4UIBase)由于没有关键代码,这里不再展示。在场景切换时,从 SceneA 切换到 SceneBSceneC 等场景使用 Application.LoadLevel() 方法。在从其他场景切换回 SceneA 之前,会调用 LaunchGame.cs 中的 DestroyAllUIGameObject() 函数,然后再调用 LoadLevel(场景A) 加载场景A。

通过以上的实现方法,就可以保证NGUI界面在场景跳转时不消失,并且能够有效地管理多个界面。

作者信息

feifeila

feifeila

共发布了 3994 篇文章