9.选服面板和功能串联

  1. 9.选服面板
    1. 9.1 拼面板
      1. 创建一个Panel取名为ChooseServerPanel作为选服面板,ChooseServerPanel下创建一个image作为面板的拖拽提示面板示意图,修改透明度对着来拼。背景图后面可以做一个专门显示背景面板的预制体,先拼其他控件就行。给登录面板添加CanvasGroup组件用于淡入淡出。
      2. 创建各种背景,和文本。创建上次登录按钮。添加左侧选择服务器滚动视图,添加右侧服务器的滚动视图。都不需要滚动条,删除滚动条后记得要把滚动视图的关联置空。
      3. 创建左侧选择服务器按钮预制体,拖入Resources/UI下。左侧选择服务器滚动视图添加垂直布局组件和自动适配大小组件,方便刷出左侧选择服务器按钮预制体。
      4. 创建右侧服务器按钮预制体,拖入Resources/UI下。右侧服务器滚动视图添加格子布局组件和自动适配大小组件,方便刷出右侧服务器按钮预制体。
    2. 9.2 数据准备
      1. 创建excel表。配置服务器id,名字,服务器状态 ,是否是新服。去网站转换json。注意不要多出空行。
      2. 复制转换后的Json文本。新建一个ServerInfo.json文件,放到StreamingAssets。
      3. 创建单个服务器数据脚本ServerInfo,定义服务器相关变量,注意变量名要和Json名一致。
      4. 在登录管理器LoginMgr脚本中,定义服务器数据列表变量,在构造函数中读取服务器数据。可以断点查看读取是否成功。
    3. 9.3 左侧按钮功能
      1. 查看左侧按钮类图
      2. 声明左侧选服按钮类ServerLeftItem。挂载到左侧选服按钮预制体上。
      3. ServerLeftItem脚本中声明按钮和显示区间内容文本的公共变量btnSelf和txtInfo。外部关联。声明了私有变量beginIndex和endIndex来存储区间范围。在Start方法中,为按钮添加点击事件监听,通知选服面板改变右侧的区间内容,这段逻辑待补充。定义InitInfo方法,用来初始化左侧选服按钮区间信息。外部传入的起始索引beginIndex和结束索引endIndex赋值给私有变量。更新显示区间内容文本为”beginIndex - endIndex区”。
    4. 9.4 右侧按钮功能
      1. 查看右侧按钮类图
      2. 声明右侧选服按钮类ServerRightItem。挂载到右侧选服按钮预制体上。
      3. ServerRightItem脚本中声明按钮本身、是否是新服、服务器状态图和名字变量btnSelf、imgNew、imgState和txtName。声明存储当前按钮所代表的服务器信息ServerInfo变量nowServerInfo。在Start为按钮添加点击事件监听,将当前点击选中的服务器ID赋值给登录管理器中的登录数据中的服务器索引LoginData.frontServerID,隐藏选服面板,显示服务器面板,隐藏选服面板逻辑等有了选服面板脚本补充。
      4. 打开图集开关,在Resource下创建图集,把服务器状态图打进图集中
      5. ServerRightItem脚本定义更新按钮显示相关的信息方法InitInfo,用于初始化或更新信息,外部将传入的服务器信息ServerInfo变量赋值给nowServerInfo。更新按钮上的信息,包括区域号和名字和是否是新服显示,先显示服务器状态图,加载图集,根据服务器状态分支设置相应的状态图或者不显示服务器状态图。
    5. 9.5 动态创建按钮
      1. 选服面板类图
      2. 创建选服面板ChooseServerPanel脚本,继承面板基类,注意名字要和场景中的对象一致,因为UI管理器是根据这个名字进行管理的。挂载到场景中的选服面板上。
      3. ChooseServerPanel脚本中声明左右滚动视图(ScrollRect),上一次登录的服务器相关信息(Text和Image)、当前选择的区间范围(Text)以及右侧按钮列表(List<GameObject>)变量。
      4. ChooseServerPanel脚本中实现Init()方法,在这个方法中要动态创建左侧的区间按钮。首先获取服务器列表的数据LoginMgr.Instance.ServerData,然后每五个服务器一组计算需要创建多少个区间按钮(num),循环创建了区间按钮,创建过程中动态加载Resources中左侧按钮预设体对象,并将其设置为左侧滚动视图的子物体,获得左侧按钮预设体上的ServerLeftItem脚本并调用脚本中的InitInfo方法,计算出当前服务器开始结束所以传入方法中,对每个区间按钮进行初始化。
      5. 把选服面板面板拖入Resources/UI文件夹下做成预制体
      6. ServerPanel脚本中补全之前未写完的改变服务器按钮监听,其中点击时实际显示服务器列表面板
      7. ChooseServerPanel脚本中实现ShowMe()方法,想调用基类的ShowMe方法。获得登录管理器中存储的上一次登录的服务器ID LoginMgr.Instance.LoginData.frontServerID,判断上一次登录的服务器ID是否小于等于0。是的话说明上一次没有选择服务器,让上一次选择服务器文本设置为无且状态图片关闭。否的话根据上一次登录的服务器ID获取到对应id的服务器信息,更新上一次选择服务器文本,状态图等,要从图集加载图片。调用更新面板方法UpdatePanel,因为这是显示自己方法,使用可以认为默认显示1-5这一组服务器,传入方法中,注意要判断服务器数量是否小于5。
      8. ChooseServerPanel脚本中定义更新面板方法UpdatePanel(int beginIndex, int endIndex),提供给外部更新当前选择区间的右侧按钮。首先更新服务器当前组显示文本txtRange中的显示内容,将其设置为”服务器 “ + beginIndex + “-“ + endIndex。删除之前创建的右侧按钮,使用for循环遍历右侧按钮列表itemList中的按钮。对每个按钮执行Destroy操作,销毁该按钮的游戏对象,删除完成后要清空itemList列表,使用itemList.Clear()方法。创建新的右侧按钮,使用for循环从beginIndex到endIndex遍历在循环内部,首先根据索引获取到当前循环的服务器信息(ServerInfo)对象,通过LoginMgr.Instance.ServerData[i - 1],然后动态加载预设体对象,并将其实例化得到的游戏对象设置为右侧滚动视图svRight.content的子物体,获取实例化的游戏对象上的ServerRightItem脚本,调用脚本InitInfo方法更新当前右侧按钮信息,将当前这次循环中的服务器信息传递给它,用于更新按钮的数据,最后将该游戏对象添加到右侧按钮列表itemList中,记录下来。
      9. ServerLeftItem脚本中,补全点击左侧按钮让选服面板更新的逻辑,得到选服面板调用UpdatePanel方法,传入自身的索引。
      10. ServerRightItem脚本中,补全点击右侧按钮隐藏选服面板的逻辑
      11. ServerPanel脚本中,补全显示自己更新服务器按钮的逻辑。得到登录管理器中登录数据信息中的id来刷新按钮。
    6. 9.6 功能串联
      1. LoginPanel脚本中确定登录按钮回调,补全登录成功后判断点击登录后要显示哪个面板。根据登录管理器中的登录数据id来判断。
      2. LoginMgr脚本中,添加清理数据方法ClearLoginData,用于注册成功后清理登录数据吗,把数据设置成默认值
      3. RegisterPanel脚本中,注册成功后要调用登录管理器的清理登录数据方法ClearLoginData,用于新注册账号的数据重置,不然会残留上一个账号的相关数据。
      4. ServerPanel脚本中,确认进入游戏按钮点击成功后存储数据,存储当前选择的服务器id。
      5. 创建游戏场景GameScene,注意要拖进BuilSetting
      6. 把背景图也做成一个背景面板预制体,可以添加适配组件。创建LoginBKPanel脚本并挂载,继承面板基类。实现空Init方法。
      7. Main脚本添加一进入就显示背景逻辑
      8. ServerPanel脚本中确定登录按钮点击成功后要隐藏背景面板
      9. LoginPanel脚本中添加自动登录逻辑,自动验证账号密码。验证正确根据服务器id选择显示哪个面板,隐藏自己。如果验证失败显示提示面板提示账号密码错误。
      10. ServerPanel脚本中返回按钮监听,返回时假如是自动登录把自动登录取消勾选,避免出现连续自动登录问题。
  2. 9.7 代码
    1. ServerLeftItem
    2. ServerRightItem
    3. ChooseServerPanel

9.选服面板


9.1 拼面板

创建一个Panel取名为ChooseServerPanel作为选服面板,ChooseServerPanel下创建一个image作为面板的拖拽提示面板示意图,修改透明度对着来拼。背景图后面可以做一个专门显示背景面板的预制体,先拼其他控件就行。给登录面板添加CanvasGroup组件用于淡入淡出。

创建各种背景,和文本。创建上次登录按钮。添加左侧选择服务器滚动视图,添加右侧服务器的滚动视图。都不需要滚动条,删除滚动条后记得要把滚动视图的关联置空。

创建左侧选择服务器按钮预制体,拖入Resources/UI下。左侧选择服务器滚动视图添加垂直布局组件和自动适配大小组件,方便刷出左侧选择服务器按钮预制体。


创建右侧服务器按钮预制体,拖入Resources/UI下。右侧服务器滚动视图添加格子布局组件和自动适配大小组件,方便刷出右侧服务器按钮预制体。



9.2 数据准备

创建excel表。配置服务器id,名字,服务器状态 ,是否是新服。去网站转换json。注意不要多出空行。



复制转换后的Json文本。新建一个ServerInfo.json文件,放到StreamingAssets。

[
{"id":1,"name":"天下无双","state":0,"isNew":false},
{"id":2,"name":"无双霸业","state":1,"isNew":false},
{"id":3,"name":"天下无敌","state":2,"isNew":false},
{"id":4,"name":"哈哈哈哈","state":3,"isNew":false},
{"id":5,"name":"黑恶阿斯","state":4,"isNew":false},
{"id":6,"name":"上的重新","state":0,"isNew":false},
{"id":7,"name":"的地方人","state":1,"isNew":false},
{"id":8,"name":"而提供给","state":2,"isNew":false},
{"id":9,"name":"天下无双1","state":3,"isNew":false},
{"id":10,"name":"天下无双2","state":4,"isNew":false},
{"id":11,"name":"天下无双3","state":0,"isNew":false},
{"id":12,"name":"天下无双4","state":1,"isNew":false},
{"id":13,"name":"天下无双5","state":2,"isNew":false},
{"id":14,"name":"天下无双6","state":3,"isNew":false},
{"id":15,"name":"天下无双7","state":4,"isNew":false},
{"id":16,"name":"天下无双8","state":0,"isNew":false},
{"id":17,"name":"天下无双9","state":1,"isNew":false},
{"id":18,"name":"天下无双10","state":2,"isNew":false},
{"id":19,"name":"天下无双11","state":3,"isNew":false},
{"id":20,"name":"天下无双12","state":4,"isNew":false},
{"id":21,"name":"天下无双13","state":0,"isNew":false},
{"id":22,"name":"天下无双14","state":1,"isNew":false},
{"id":23,"name":"天下无双15","state":2,"isNew":false},
{"id":24,"name":"天下无双16","state":3,"isNew":false},
{"id":25,"name":"天下无双17","state":4,"isNew":true},
{"id":26,"name":"天下无双18","state":4,"isNew":true}
]

创建单个服务器数据脚本ServerInfo,定义服务器相关变量,注意变量名要和Json名一致。

/// <summary>
/// 单个服务器数据
/// </summary>
public class ServerInfo
{
    //区号 ID
    public int id;
    //服务器名
    public string name;
    //服务器状态 0~4就是5种状态
    public int state;
    //是否是新服
    public bool isNew;
}

在登录管理器LoginMgr脚本中,定义服务器数据列表变量,在构造函数中读取服务器数据。可以断点查看读取是否成功。

//所有服务器数据
private List<ServerInfo> serverData;
public List<ServerInfo> ServerData => serverData;

private LoginMgr()
{
    //读取服务器数据
    serverData = JsonMgr.Instance.LoadData<List<ServerInfo>>("ServerInfo");
}

9.3 左侧按钮功能

查看左侧按钮类图

声明左侧选服按钮类ServerLeftItem。挂载到左侧选服按钮预制体上。

ServerLeftItem脚本中声明按钮和显示区间内容文本的公共变量btnSelf和txtInfo。外部关联。声明了私有变量beginIndex和endIndex来存储区间范围。在Start方法中,为按钮添加点击事件监听,通知选服面板改变右侧的区间内容,这段逻辑待补充。定义InitInfo方法,用来初始化左侧选服按钮区间信息。外部传入的起始索引beginIndex和结束索引endIndex赋值给私有变量。更新显示区间内容文本为”beginIndex - endIndex区”。

public class ServerLeftItem : MonoBehaviour
{
    //按钮自己
    public Button btnSelf;
    //显示的区间内容
    public Text txtInfo;
    
    //区间范围
    private int beginIndex;
    private int endIndex;
    
    void Start()
    {
        btnSelf.onClick.AddListener(()=> { 
            
            //通知选服面板 改变右侧的区间内容
            
        });
    }
    
    public void InitInfo(int beginIndex, int endIndex)
    {
        //记录当前区间按钮的 区间值
        this.beginIndex = beginIndex;
        this.endIndex = endIndex;
        
        //把区间显示的内容 更新了
        txtInfo.text = beginIndex + " - " + endIndex + "区";
    }
    
}

9.4 右侧按钮功能

查看右侧按钮类图

声明右侧选服按钮类ServerRightItem。挂载到右侧选服按钮预制体上。

ServerRightItem脚本中声明按钮本身、是否是新服、服务器状态图和名字变量btnSelf、imgNew、imgState和txtName。声明存储当前按钮所代表的服务器信息ServerInfo变量nowServerInfo。在Start为按钮添加点击事件监听,将当前点击选中的服务器ID赋值给登录管理器中的登录数据中的服务器索引LoginData.frontServerID,隐藏选服面板,显示服务器面板,隐藏选服面板逻辑等有了选服面板脚本补充。

public class ServerRightItem : MonoBehaviour
{
    //按钮本身
    public Button btnSelf;
    //是否是新服
    public Image imgNew;
    //状态图
    public Image imgState;
    //名字
    public Text txtName;
    
    //当前按钮 代表哪个服务器 之后 会使用其中的数据
    public ServerInfo nowServerInfo;
    
    void Start()
    {
        btnSelf.onClick.AddListener(()=> {
            //记录当前你选择的服务器
            LoginMgr.Instance.LoginData.frontServerID = nowServerInfo.id;
            
            //隐藏 选服面板
            
            //显示 服务器面板
            UIManager.Instance.ShowPanel<ServerPanel>();
        });
    }
}

打开图集开关,在Resource下创建图集,把服务器状态图打进图集中



ServerRightItem脚本定义更新按钮显示相关的信息方法InitInfo,用于初始化或更新信息,外部将传入的服务器信息ServerInfo变量赋值给nowServerInfo。更新按钮上的信息,包括区域号和名字和是否是新服显示,先显示服务器状态图,加载图集,根据服务器状态分支设置相应的状态图或者不显示服务器状态图。

/// <summary>
/// 初始化方法 用于 更新按钮显示相关
/// </summary>
/// <param name="info"></param>
public void InitInfo(ServerInfo info)
{
    //记录下数据
    nowServerInfo = info;

    //更新按钮上的信息
    txtName.text = info.id + "区 " + info.name;
    //是否是新服
    imgNew.gameObject.SetActive(info.isNew);
    //一开让状态图 显示
    imgState.gameObject.SetActive(true);
    //状态
    //加载图集
    SpriteAtlas sa = Resources.Load<SpriteAtlas>("Login");
    switch (info.state)
    {
        case 0:
            imgState.gameObject.SetActive(false);
            break;
        case 1://流畅
            imgState.sprite = sa.GetSprite("ui_DL_liuchang_01");
            break;
        case 2://繁忙
            imgState.sprite = sa.GetSprite("ui_DL_fanhua_01");
            break;
        case 3://火爆
            imgState.sprite = sa.GetSprite("ui_DL_huobao_01");
            break;
        case 4://维护
            imgState.sprite = sa.GetSprite("ui_DL_weihu_01");
            break;
    }
}

9.5 动态创建按钮

选服面板类图

创建选服面板ChooseServerPanel脚本,继承面板基类,注意名字要和场景中的对象一致,因为UI管理器是根据这个名字进行管理的。挂载到场景中的选服面板上。

ChooseServerPanel脚本中声明左右滚动视图(ScrollRect),上一次登录的服务器相关信息(Text和Image)、当前选择的区间范围(Text)以及右侧按钮列表(List<GameObject>)变量。

//左右的滚动视图
public ScrollRect svLeft;
public ScrollRect svRight;

//上一次登录的服务器相关信息
public Text txtName;
public Image imgState;

//当前选择的区间范围
public Text txtRange;

//用于存储右侧按钮们
private List<GameObject> itemList = new List<GameObject>();

ChooseServerPanel脚本中实现Init()方法,在这个方法中要动态创建左侧的区间按钮。首先获取服务器列表的数据LoginMgr.Instance.ServerData,然后每五个服务器一组计算需要创建多少个区间按钮(num),循环创建了区间按钮,创建过程中动态加载Resources中左侧按钮预设体对象,并将其设置为左侧滚动视图的子物体,获得左侧按钮预设体上的ServerLeftItem脚本并调用脚本中的InitInfo方法,计算出当前服务器开始结束所以传入方法中,对每个区间按钮进行初始化。

public override void Init()
{
    //动态创建左侧的 区间按钮

    //获取到服务器列表的数据
    List<ServerInfo> infoList = LoginMgr.Instance.ServerData;

    //得到一共要循环创建多少个区间按钮 
    //由于向下取整 所以我们+1  就代表 平均分成了num个按钮
    int num = infoList.Count / 5 + 1;

    //循环创建 一个一个的 区间按钮
    for (int i = 0; i < num; i++)
    {
        //动态创建预设体对象
        GameObject item = Instantiate(Resources.Load<GameObject>("UI/ServerLeftItem"));
        item.transform.SetParent(svLeft.content, false);
        //初始化
        ServerLeftItem serverLeft = item.GetComponent<ServerLeftItem>();
        int beginIndex = i * 5 + 1;
        int endIndex = 5 * (i + 1);
        //判断 最大 是不是超过了 服务器的总数
        if (endIndex > infoList.Count)
            endIndex = infoList.Count;
        //初始化 区间按钮
        serverLeft.InitInfo(beginIndex, endIndex);
    }
}

把选服面板面板拖入Resources/UI文件夹下做成预制体

ServerPanel脚本中补全之前未写完的改变服务器按钮监听,其中点击时实际显示服务器列表面板

btnChange.onClick.AddListener(()=> {
    //显示服务器列表面板
    UIManager.Instance.ShowPanel<ChooseServerPanel>();
    //隐藏自己
    UIManager.Instance.HidePanel<ServerPanel>();
});

ChooseServerPanel脚本中实现ShowMe()方法,想调用基类的ShowMe方法。获得登录管理器中存储的上一次登录的服务器ID LoginMgr.Instance.LoginData.frontServerID,判断上一次登录的服务器ID是否小于等于0。是的话说明上一次没有选择服务器,让上一次选择服务器文本设置为无且状态图片关闭。否的话根据上一次登录的服务器ID获取到对应id的服务器信息,更新上一次选择服务器文本,状态图等,要从图集加载图片。调用更新面板方法UpdatePanel,因为这是显示自己方法,使用可以认为默认显示1-5这一组服务器,传入方法中,注意要判断服务器数量是否小于5。

public override void ShowMe()
{
    base.ShowMe();

    //显示自己时 
    //应该初始化 上一次选择的服务器 
        
    int id = LoginMgr.Instance.LoginData.frontServerID;
    if (id <= 0 )
    {
        txtName.text = "无";
        imgState.gameObject.SetActive(false);
    }
    else
    {
        //根据上一次登录的 服务器ID 获取到 服务器信息 用于界面数据更新
        ServerInfo info = LoginMgr.Instance.ServerData[id - 1];
        //拼接显示上一次登录的服务器名字
        txtName.text = info.id + "区  " + info.name;
        //一开让状态图 显示
        imgState.gameObject.SetActive(true);
        //状态
        //加载图集
        SpriteAtlas sa = Resources.Load<SpriteAtlas>("Login");
        switch (info.state)
        {
            case 0:
                imgState.gameObject.SetActive(false);
                break;
            case 1://流畅
                imgState.sprite = sa.GetSprite("ui_DL_liuchang_01");
                break;
            case 2://繁忙
                imgState.sprite = sa.GetSprite("ui_DL_fanhua_01");
                break;
            case 3://火爆
                imgState.sprite = sa.GetSprite("ui_DL_huobao_01");
                break;
            case 4://维护
                imgState.sprite = sa.GetSprite("ui_DL_weihu_01");
                break;
        }
    }

    //更新当前的选择的区间
    UpdatePanel(1, 5 > LoginMgr.Instance.ServerData.Count ? LoginMgr.Instance.ServerData.Count : 5);
}

ChooseServerPanel脚本中定义更新面板方法UpdatePanel(int beginIndex, int endIndex),提供给外部更新当前选择区间的右侧按钮。首先更新服务器当前组显示文本txtRange中的显示内容,将其设置为”服务器 “ + beginIndex + “-“ + endIndex。删除之前创建的右侧按钮,使用for循环遍历右侧按钮列表itemList中的按钮。对每个按钮执行Destroy操作,销毁该按钮的游戏对象,删除完成后要清空itemList列表,使用itemList.Clear()方法。创建新的右侧按钮,使用for循环从beginIndex到endIndex遍历在循环内部,首先根据索引获取到当前循环的服务器信息(ServerInfo)对象,通过LoginMgr.Instance.ServerData[i - 1],然后动态加载预设体对象,并将其实例化得到的游戏对象设置为右侧滚动视图svRight.content的子物体,获取实例化的游戏对象上的ServerRightItem脚本,调用脚本InitInfo方法更新当前右侧按钮信息,将当前这次循环中的服务器信息传递给它,用于更新按钮的数据,最后将该游戏对象添加到右侧按钮列表itemList中,记录下来。

/// <summary>
/// 提供给其它地方 用于更新 当前选择区间的右侧按钮
/// </summary>
/// <param name="beginIndex"></param>
/// <param name="endIndex"></param>
public void UpdatePanel(int beginIndex, int endIndex)
{
    // 更新服务器区间显示
    txtRange.text = "服务器 " + beginIndex + "-" + endIndex;

    // 第一步:删除之前的单个按钮
    for (int i = 0; i < itemList.Count; i++)
    {
        //删除之前的 对象
        Destroy(itemList[i]);
    }
    // 删除完成后 一定要清空列表
    itemList.Clear();

    // 第二步:创建新的按钮
    for (int i = beginIndex; i <= endIndex; i++)
    {
        //首先获取 服务器信息
        ServerInfo nowInfo = LoginMgr.Instance.ServerData[i - 1];

        //动态创建预设体
        GameObject serverItem = Instantiate(Resources.Load<GameObject>("UI/ServerRightItem"));
        serverItem.transform.SetParent(svRight.content, false);
        //根据信息 更新按钮数据
        ServerRightItem rightItem = serverItem.GetComponent<ServerRightItem>();
        rightItem.InitInfo(nowInfo);

        //创建成功后 把它记录到列表中
        itemList.Add(serverItem);
    }
}

ServerLeftItem脚本中,补全点击左侧按钮让选服面板更新的逻辑,得到选服面板调用UpdatePanel方法,传入自身的索引。

void Start()
{
    btnSelf.onClick.AddListener(()=> {

        //通知选服面板 改变右侧的区间内容
        ChooseServerPanel panel = UIManager.Instance.GetPanel<ChooseServerPanel>();
        panel.UpdatePanel(beginIndex, endIndex);
    });
}

ServerRightItem脚本中,补全点击右侧按钮隐藏选服面板的逻辑

void Start()
{
    btnSelf.onClick.AddListener(()=> {
        //记录当前你选择的服务器
        LoginMgr.Instance.LoginData.frontServerID = nowServerInfo.id;

        //隐藏 选服面板
        UIManager.Instance.HidePanel<ChooseServerPanel>();

        //显示 服务器面板
        UIManager.Instance.ShowPanel<ServerPanel>();
    });
}

ServerPanel脚本中,补全显示自己更新服务器按钮的逻辑。得到登录管理器中登录数据信息中的id来刷新按钮。

public override void ShowMe()
{
    base.ShowMe();

    //显示自己的时候 更新 当前选择的服务器名字
    //之后 我们会通过 记录的上一次登录的服务器ID 来更新内容
    int id = LoginMgr.Instance.LoginData.frontServerID;
    if(id <= 0)
    {
        txtName.text = "无选择";
    }
    else
    {
        ServerInfo info = LoginMgr.Instance.ServerData[id - 1];
        txtName.text = info.id + "区 " + info.name;
    }
}

9.6 功能串联

LoginPanel脚本中确定登录按钮回调,补全登录成功后判断点击登录后要显示哪个面板。根据登录管理器中的登录数据id来判断。

//点击登录 做什么
btnSure.onClick.AddListener(() => {
    //点击登录后 要验证用户民密码 是否正确 
    
    //判断是否合法
    if (inputPW.text.Length <= 6 || inputUN.text.Length <= 6) {
        //提示不合法 
        TipPanel panel = UIManager.Instance.ShowPanel<TipPanel>();
        //改变提示面板上提示的内容
        panel.ChangeInfo("账号和密码都必须大于6位");
        return;
    }
    
    //验证 用户名和密码 是否 通过
    if (LoginMgr.Instance.CheckInfo(inputUN.text, inputPW.text)) {
        //登录成功
        
        //记录数据
        LoginMgr.Instance.LoginData.userName = inputUN.text;
        LoginMgr.Instance.LoginData.passWord = inputPW.text;
        LoginMgr.Instance.LoginData.rememberPw = togPW.isOn;
        LoginMgr.Instance.LoginData.autoLogin = togAuto.isOn;
        LoginMgr.Instance.SaveLoginData();
        
        //根据服务器信息 来进行判断 显示哪个面板
        if (LoginMgr.Instance.LoginData.frontServerID <= 0) {
            //如果从来没有选择过服务器 id为-1时  就应该直接打开 选服面板
            UIManager.Instance.ShowPanel<ChooseServerPanel>();
        } else {
            //打开我们的服务器面板
            UIManager.Instance.ShowPanel<ServerPanel>();
        }
        
        //隐藏自己
        UIManager.Instance.HidePanel<LoginPanel>();
    } else {
        //登录失败
        UIManager.Instance.ShowPanel<TipPanel>().ChangeInfo("账号或密码错误");
    }
});

LoginMgr脚本中,添加清理数据方法ClearLoginData,用于注册成功后清理登录数据吗,把数据设置成默认值

//主要用于 注册成功后 清理登录数据
public void ClearLoginData() {
    loginData.frontServerID = 0;
    loginData.autoLogin = false;
    loginData.rememberPw = false;
}

RegisterPanel脚本中,注册成功后要调用登录管理器的清理登录数据方法ClearLoginData,用于新注册账号的数据重置,不然会残留上一个账号的相关数据。

btnSure.onClick.AddListener(() => { 
        
    //判断输入的账号密码 是否合理
    if (inputPW.text.Length <= 6 || inputUN.text.Length <= 6 ) {
        //提示不合法 
        TipPanel panel = UIManager.Instance.ShowPanel<TipPanel>();
        //改变提示面板上提示的内容
        panel.ChangeInfo("账号和密码都必须大于6位");
        return;
    }
            
    //去注册账号密码
    if (LoginMgr.Instance.RegisterUser(inputUN.text, inputPW.text)) {
        //清理登录数据 用于 新注册账号的 数据重置 不然会残留上一个账号的相关数据
        LoginMgr.Instance.ClearLoginData();
        
        //注册成功
        //显示 登录面板
        LoginPanel loginPanel = UIManager.Instance.ShowPanel<LoginPanel>();
        //更新登录面板上的 用户名和密码
        loginPanel.SetInfo(inputUN.text, inputPW.text);
        
        //隐藏自己
        UIManager.Instance.HidePanel<RegisterPanel>();
    } else {
        //提示别人 用户名已经存在 
        TipPanel tipPanel = UIManager.Instance.ShowPanel<TipPanel>();
        //改变提示内容
        tipPanel.ChangeInfo("用户名已存在");
        
        //方便别人重新输入
        inputUN.text = "";
        inputPW.text = "";
    }
    
});

ServerPanel脚本中,确认进入游戏按钮点击成功后存储数据,存储当前选择的服务器id。

btnStart.onClick.AddListener(() => {
    
    //进入游戏
    //由于过场景 Canvas对象不会被移除 所以 下面的面板应该也要隐藏了
    //隐藏自己
    UIManager.Instance.HidePanel<ServerPanel>();
    //隐藏我们的 登录背景图面板
    UIManager.Instance.HidePanel<LoginBKPanel>();
    
    //存储数据的目的 是为了 存储到它当前选择的服务器ID
    LoginMgr.Instance.SaveLoginData();
    
    //切场景
    SceneManager.LoadScene("GameScene");
    
});

创建游戏场景GameScene,注意要拖进BuilSetting

把背景图也做成一个背景面板预制体,可以添加适配组件。创建LoginBKPanel脚本并挂载,继承面板基类。实现空Init方法。

public class LoginBKPanel : BasePanel
{
    public override void Init()
    {
       
    }
}

Main脚本添加一进入就显示背景逻辑

public class Main : MonoBehaviour
{    
    void Start()
    {
        //显示 提示面板 测试
        //TipPanel tipPanel = UIManager.Instance.ShowPanel<TipPanel>();
        //tipPanel.ChangeInfo("测试提示内容改变");
        
        //一进游戏 就应该显示 登录面板
        UIManager.Instance.ShowPanel<LoginBKPanel>();
        UIManager.Instance.ShowPanel<LoginPanel>();
    }
}

ServerPanel脚本中确定登录按钮点击成功后要隐藏背景面板

//隐藏我们的 登录背景图面板
UIManager.Instance.HidePanel<LoginBKPanel>();

LoginPanel脚本中添加自动登录逻辑,自动验证账号密码。验证正确根据服务器id选择显示哪个面板,隐藏自己。如果验证失败显示提示面板提示账号密码错误。

public override void ShowMe()
{
    base.ShowMe();
    //显示自己时  根据数据 更新面板上的内容
    
    //得到数据
    LoginData loginData = LoginMgr.Instance.LoginData;
    
    //初始化面板显示
    //更新 两个多选框
    togPW.isOn = loginData.rememberPw;
    togAuto.isOn = loginData.autoLogin;
    
    //更新账号密码
    inputUN.text = loginData.userName;
    //根据你是否上一次勾选了记住密码 来决定是否 更新密码
    if (togPW.isOn)
        inputPW.text = loginData.passWord;
    
    //如果是自动登录 做什么
    if (togAuto.isOn) {
        //自动去验证账号密码相关
        //验证用户名密码
        if (LoginMgr.Instance.CheckInfo(inputUN.text, inputPW.text)) {
            //根据服务器信息 来进行判断 显示哪个面板
            if (LoginMgr.Instance.LoginData.frontServerID <= 0) {
                //如果从来没有选择过服务器 id为-1时  就应该直接打开 选服面板
                UIManager.Instance.ShowPanel<ChooseServerPanel>();
            } else {
                //打开我们的服务器面板
                UIManager.Instance.ShowPanel<ServerPanel>();
            }
            
            //隐藏自己
            UIManager.Instance.HidePanel<LoginPanel>(false);
        } else {
            TipPanel panel = UIManager.Instance.ShowPanel<TipPanel>();
            panel.ChangeInfo("账号密码错误");
        }
    }
}

ServerPanel脚本中返回按钮监听,返回时假如是自动登录把自动登录取消勾选,避免出现连续自动登录问题。

btnBack.onClick.AddListener(() => {
    //避免 自动登录时 返回登录界面 出现问题
    if (LoginMgr.Instance.LoginData.autoLogin)
        LoginMgr.Instance.LoginData.autoLogin = false;
    
    //显示登录面板
    UIManager.Instance.ShowPanel<LoginPanel>();
    //隐藏自己
    UIManager.Instance.HidePanel<ServerPanel>();
});

9.7 代码

ServerLeftItem

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ServerLeftItem : MonoBehaviour
{
    //按钮自己
    public Button btnSelf;
    //显示的区间内容
    public Text txtInfo;

    //区间范围
    private int beginIndex;
    private int endIndex;

    void Start()
    {
        btnSelf.onClick.AddListener(() =>
        {
            //通知选服面板 改变右侧的区间内容
            ChooseServerPanel panel = UIManager.Instance.GetPanel<ChooseServerPanel>();
            panel.UpdatePanel(beginIndex, endIndex);
        });
    }

    public void InitInfo(int beginIndex, int endIndex)
    {
        //记录当前区间按钮的 区间值
        this.beginIndex = beginIndex;
        this.endIndex = endIndex;

        //把区间显示的内容 更新了
        txtInfo.text = beginIndex + " - " + endIndex + "区";
    }

}

ServerRightItem

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.U2D;
using UnityEngine.UI;

public class ServerRightItem : MonoBehaviour
{
    //按钮本身
    public Button btnSelf;
    //是否是新服
    public Image imgNew;
    //状态图
    public Image imgState;
    //名字
    public Text txtName;

    //当前按钮 代表哪个服务器 之后 会使用其中的数据
    public ServerInfo nowServerInfo;

    void Start()
    {
        btnSelf.onClick.AddListener(() =>
        {
            //记录当前你选择的服务器
            LoginMgr.Instance.LoginData.frontServerID = nowServerInfo.id;

            //隐藏 选服面板
            UIManager.Instance.HidePanel<ChooseServerPanel>();

            //显示 服务器面板
            UIManager.Instance.ShowPanel<ServerPanel>();
        });
    }

    /// <summary>
    /// 初始化方法 用于 更新按钮显示相关
    /// </summary>
    /// <param name="info"></param>
    public void InitInfo(ServerInfo info)
    {
        //记录下数据
        nowServerInfo = info;

        //更新按钮上的信息
        txtName.text = info.id + "区 " + info.name;
        //是否是新服
        imgNew.gameObject.SetActive(info.isNew);
        //一开让状态图 显示
        imgState.gameObject.SetActive(true);
        //状态
        //加载图集
        SpriteAtlas sa = Resources.Load<SpriteAtlas>("Login");
        switch (info.state)
        {
            case 0:
                imgState.gameObject.SetActive(false);
                break;
            case 1://流畅
                imgState.sprite = sa.GetSprite("ui_DL_liuchang_01");
                break;
            case 2://繁忙
                imgState.sprite = sa.GetSprite("ui_DL_fanhua_01");
                break;
            case 3://火爆
                imgState.sprite = sa.GetSprite("ui_DL_huobao_01");
                break;
            case 4://维护
                imgState.sprite = sa.GetSprite("ui_DL_weihu_01");
                break;
        }
    }
}

ChooseServerPanel

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.U2D;
using UnityEngine.UI;

public class ChooseServerPanel : BasePanel
{
    //左右的滚动视图
    public ScrollRect svLeft;
    public ScrollRect svRight;

    //上一次登录的服务器相关信息
    public Text txtName;
    public Image imgState;

    //当前选择的区间范围
    public Text txtRange;

    //用于存储右侧按钮们
    private List<GameObject> itemList = new List<GameObject>();

    public override void Init()
    {
        //动态创建左侧的 区间按钮

        //获取到服务器列表的数据
        List<ServerInfo> infoList = LoginMgr.Instance.ServerData;

        //得到一共要循环创建多少个区间按钮 
        //由于向下取整 所以我们+1  就代表 平均分成了num个按钮
        int num = infoList.Count / 5 + 1;

        //循环创建 一个一个的 区间按钮
        for (int i = 0; i < num; i++)
        {
            //动态创建预设体对象
            GameObject item = Instantiate(Resources.Load<GameObject>("UI/ServerLeftItem"));
            item.transform.SetParent(svLeft.content, false);
            //初始化
            ServerLeftItem serverLeft = item.GetComponent<ServerLeftItem>();
            int beginIndex = i * 5 + 1;
            int endIndex = 5 * (i + 1);
            //判断 最大 是不是超过了 服务器的总数
            if (endIndex > infoList.Count)
                endIndex = infoList.Count;
            //初始化 区间按钮
            serverLeft.InitInfo(beginIndex, endIndex);
        }
    }

    public override void ShowMe()
    {
        base.ShowMe();

        //显示自己时 
        //应该初始化 上一次选择的服务器 
        
        int id = LoginMgr.Instance.LoginData.frontServerID;
        if (id <= 0 )
        {
            txtName.text = "无";
            imgState.gameObject.SetActive(false);
        }
        else
        {
            //根据上一次登录的 服务器ID 获取到 服务器信息 用于界面数据更新
            ServerInfo info = LoginMgr.Instance.ServerData[id - 1];
            //拼接显示上一次登录的服务器名字
            txtName.text = info.id + "区  " + info.name;
            //一开让状态图 显示
            imgState.gameObject.SetActive(true);
            //状态
            //加载图集
            SpriteAtlas sa = Resources.Load<SpriteAtlas>("Login");
            switch (info.state)
            {
                case 0:
                    imgState.gameObject.SetActive(false);
                    break;
                case 1://流畅
                    imgState.sprite = sa.GetSprite("ui_DL_liuchang_01");
                    break;
                case 2://繁忙
                    imgState.sprite = sa.GetSprite("ui_DL_fanhua_01");
                    break;
                case 3://火爆
                    imgState.sprite = sa.GetSprite("ui_DL_huobao_01");
                    break;
                case 4://维护
                    imgState.sprite = sa.GetSprite("ui_DL_weihu_01");
                    break;
            }
        }
        
        //更新当前的选择的区间
        UpdatePanel(1, 5 > LoginMgr.Instance.ServerData.Count ? LoginMgr.Instance.ServerData.Count : 5);
    }

    /// <summary>
    /// 提供给其它地方 用于更新 当前选择区间的右侧按钮
    /// </summary>
    /// <param name="beginIndex"></param>
    /// <param name="endIndex"></param>
    public void UpdatePanel(int beginIndex, int endIndex)
    {
        // 更新服务器区间显示
        txtRange.text = "服务器 " + beginIndex + "-" + endIndex;
        
        // 第一步:删除之前的单个按钮
        for (int i = 0; i < itemList.Count; i++)
        {
            //删除之前的 对象
            Destroy(itemList[i]);
        }
        // 删除完成后 一定要清空列表
        itemList.Clear();
        
        // 第二步:创建新的按钮
        for (int i = beginIndex; i <= endIndex; i++)
        {
            //首先获取 服务器信息
            ServerInfo nowInfo = LoginMgr.Instance.ServerData[i - 1];
        
            //动态创建预设体
            GameObject serverItem = Instantiate(Resources.Load<GameObject>("UI/ServerRightItem"));
            serverItem.transform.SetParent(svRight.content, false);
            //根据信息 更新按钮数据
            ServerRightItem rightItem = serverItem.GetComponent<ServerRightItem>();
            rightItem.InitInfo(nowInfo);
        
            //创建成功后 把它记录到列表中
            itemList.Add(serverItem);
        }
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏