NGUI 多场景情况下 管理多个界面

简单的说就是在一个AllUI场景中,所有场景所需要的界面都挂在一个Empty GameObject下,然后这个Empty GameObject在代码中DontDestroyOnLoad,但是回到这个AllUI场景时根据实际情况决定要不要Destroy掉!具体如下:

因为我们的游戏场景分布是这样的情况:
注册/登陆界面 所在的场景A,游戏场景B、世界场景C、战斗场景D。

为了便于界面的管理(比如,你打开界面1->界面2->界面3,然后又跳转来跳转去的,这个时候如果将所有界面继承一个基类UIBase,然后保存在一个字典里,显示一个全屏界面就可以用一个for循环解决);

主要的做法就是:将所有的界面都放在A场景中,游戏一开始先加载场景A,然后所有的界面(UIRoot)都在同一个游戏对象下(比如叫AllUIGameObject),然后在代码里DontDestroyOnLoad(AllGameObject),这样切换到其他场景(B、C、D)时,界面可以得以继续存在,如果再返回A场景(比如切换账号回到登陆界面的情况下),这个时候因为又要重头开始走登陆的流程,上一个账号的数据很多都无效了,因此Destroy掉前面的AllUIGameObject对象(当然有一些角色的数据如果用了static或者单体等保存下来的话,还是要动态的去重置的),再重新按照上述的步骤加载场景A走相同的流程就可以了(这里的指的流程简单的就指下面的LaunchGame.cs脚本中的start()函数)。

因为使用DestroyOnLoad(Obj),来回切换obj所在的场景时,会出现多份Obj的克隆,为此,在网上搜了一些方法,比如用个标志位来判断是否已经克隆,或者用单例判断Obj是否已经被初始化过,但都一样会出现重复Obj的情况!因此改为了上述所说的思路。

LaunchGame.cs: 

 1 using UnityEngine;
 2 
 3 public class LaunchGame : MonoBehaviour
 4 {
 5     public GameObject mAllUIGameObject = null;
 6 
 7     private static LaunchGame mInstance = null;
 8     public static LaunchGame Instance
 9     {
10         get
11         {
12             return mInstance;
13         }
14         private set
15         {
16 
17         }
18     }
19     void Start ()
20     {
21         if (mInstance == null)
22         {
23             Output.Log("LaunchGame.Start(), mInstance == null");
24             mInstance = this;
25         }
26 
27         DontDestroyOnLoad(mAllUIGameObject);
28 
29         UIManager.Instance.Init();
30 
31         Output.Log("LaunchGame.Start()");
32     }
33 
34     void Update ()
35     {
36 
37     }
38 
39     public void DestroyAllUIGameObject()
40     {
41         Destroy(mAllUIGameObject);
42     }
43 }

UIManager.cs:

 1 using System.Collections.Generic;
 2 
 3 // 面板类型
 4 public enum UIType
 5 {
 6     UI1,
 7     UI2,
 8     UI3,
 9     UI4,
10 }
11 
12 // 界面逻辑管理器
13 public class UIManager : Singleton<UIManager>
14 {
15     public UI1 ui1 = null;
16     public UI2 ui2 = null;
17     public UI3 ui3 = null;
18     public UI4 ui4 = null;
19 
20     Dictionary<UIType, UIBase> mUIDic = new Dictionary<UIType, UIBase>();
21     
22     // 初始化界面逻辑
23     public void Init()
24     {
25         CheckMembers();
26         InitAllPanel();
27     }
28 
29     // 检测成员变量是否有效
30     void CheckMembers()
31     {
32         Assert.IsNotNull(ui1, "UIManager.CheckMembers(), ui1 is null object!");
33         Assert.IsNotNull(ui2, "UIManager.CheckMembers(), ui2 is null object!");
34         Assert.IsNotNull(ui3, "UIManager.CheckMembers(), ui3 is null object!");
35         Assert.IsNotNull(ui4, "UIManager.CheckMembers(), ui4 is null object!");
36     }
37 
38     // 初始化所有面板
39     void InitAllPanel()
40     {
41         mUIDic.Add(UIType.UI1, ui1);
42         mUIDic.Add(UIType.UI2, ui2);
43         mUIDic.Add(UIType.UI3, ui3);
44         mUIDic.Add(UIType.UI4, ui4);
45 
46         foreach (UIBase ui in mUIDic.Values)
47         {
48             if (ui.m_panel != null)
49             {
50                 ui.CheckWidget();
51                 ui.Init();
52                 ui.BindingEvent();
53                 ui.Reset();
54             }
55         }
56     }
57 
58     // 显示指定面板
59     public void ShowPanel(UIType type)
60     {
61         foreach (KeyValuePair<UIType, UIBase> item in mUIDic)
62         {
63             if (type == item.Key)
64             {
65                 item.Value.Show();
66             }
67             else
68             {
69                 item.Value.Hide();
70             }
71         }
72     }
73 }


其他脚本(诸如UI1..UI4、UIBase)就不贴了,都没什么,在SceneA->SceneB->SceneC都是用Application.LoadLevel(),而在Scene X -> SceneA之前,就会调用LaunchGame.cs中的函数DestroyAllUIGameObject(),然后才LoadLevel(场景A)。

 

以上就是大致思路及实现,如果存在不好的方面,麻烦告知,不胜感激!

 

update:2014.11.29

之后在实现过程中,发现上述思路存在问题,修改如下:UI统一放在LoginScene场景中,游戏启动的时候会先加载一个LaunchGameScene场景,其中脚本负责做的事情就是使游戏中使用单体对象不释放,主要就是使用DontDestroyOnLoad函数,然后才跳转到LoginScene进行登录流程,之后才进入GameScene。然后注销账号回到登录界面的时候只是切换到LoginScene场景中,而没有切换到LaunchGameScene场景!具体流程如下:

如果有更多的场景,同理一样!

此思路如果存在什么问题,麻烦指教,谢谢!!

 

转载于:https://www.cnblogs.com/AlphaAI/p/3960044.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值