unity学习(7)——handler 游戏内部消息机制(暂不涉及网络)

1.NetWorkScript这个脚本是挂在Canvas上的,并不是Camera上。

2.在Scripts文件夹下创建一个Handler的子文件夹,在里面创建一个脚本LoginHandler

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

public class LoginHandler : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
    public void OnMessage(SocketModel model)
    {
        Debug.Log("这里是LoginHandler.cs");
        //获取账号密码
        //发送给服务器
    }
}

3.在Handler文件夹下创建一个起到总体调度消息的脚本MessageManager,挂给canvas。

 using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using minna;
public class MessageManager : MonoBehaviour
{
    // Start is called before the first frame update
    private LoginHandler login;//定义
    void Start()//初始化时
    {
        login = GetComponent();//从脚本获得组件,这样是可以的
    }

    // Update is called once per frame
    void Update()
    {
        //从消息队列
        List list=NetWorkScript.getInstance().getList();//游戏控件消息队列,不涉及网络
        for (int i = 0; i < 8; i++)//每帧8条信息
        {
            if (list.Count > 0)
            {
                SocketModel model = list[0];//后面有取出信息的
                OnMessage(model);//处理当前的第一条信息
                list.RemoveAt(0);
            }
            else
            {
                break;//无消息跳出循环
            }
        }
    }
    public void OnMessage(SocketModel model)
    {
        //处理当前信息
        switch (model.type)
        {
            case Protocol.LOGIN:
            {
                login.OnMessage(model);//调用的是LoginHandle中的方法
                break;
            }
            case Protocol.USER:
            {
                break;
            }
            case Protocol.MAP:
            {
                break;
            }
            default:
            {
                break;
            }
        }
    }
}

4.在NetWorkScripts脚本中补充一个简单的getList()函数

public List getList()
{
    return messageList;
}

5.首先,在SocketModel脚本中增加一个Protocol类,内容如下,用来说明model中第一个参数type的内容,整体就是起到了一个命名的作用。

然后,还是在SocketModel中增加LoginProtocol,也是起到一个宏命名的功能。

最后,因为c#不能导入单个类,c#中只能引用命名空间中的类,新增一个命名空间的同时,在其中增加一个账号密码的类LoginDTO。

还需要再在minna中补一个json编解码的类,叫Coding,同时还需要一个json的dll。

using LitJson;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//using Model.SocketModel;不能导入单个类,c#中只能引用命名空间中的类!

//这个脚本就是起到一个宏命名的作用,不用大惊小怪
    public class SocketModel
    {
        public int type { get; set; }//具体定义见下面的Protocol
        public int area { get; set; }
        public int command { get; set; }
        public string message { get; set; }
    }
namespace minna//不同文件夹之间实现通用,有意义的
{
    public class Protocol//type的具体分类v
    {
        public const int LOGIN = 0;
        public const int MAP = 1;
        public const int USER = 2;
    }
    public class LoginProtocol
    {
        public const int LOGIN_CREQ = 0;
        public const int LOGIN_SRES = 1;
        public const int REG_CREQ = 2;
        public const int REG_SRES = 3;
    }
    public class LoginDTO
    {
        public string userName;
        public string passWord;
    }
    class Coding
    {
        public static string encode(T model)
        {
            return JsonMapper.ToJson(model);
        }

        public static T decode(string message)
        {
            return JsonMapper.ToObject(message);
        }
    }
}

7,在RegPanelScript脚本中增加功能,分别为登录界面和注册界面接受账号和密码,然后加工生成消息的内容。(这两个部分的消息体是一样的)下面代码是登录部分的。

using UnityEngine;
using System.Collections;
using System.Security.Cryptography.X509Certificates;
using UnityEngine.UI;
using TMPro;
using System;
using Unity.VisualScripting;
using minna;



public class RegPanelScript : MonoBehaviour {

    //public UILabel accountLabel;
    //public UILabel passwordLabel;
    //public InputField inputField;

    void Start () {
        gameObject.SetActive (false);//加载时隐藏注册panel
        //gameObject.SetActive(false);
    }
    public void Open()//主界面右边注册
	{
        gameObject.SetActive(true);
    }
    public void Close()//panel退出
    {
        gameObject.SetActive(false);
    }
    public void Exit()//红按钮退出
    {
        #if UNITY_EDITOR
            UnityEditor.EditorApplication.isPlaying = false;//在Unity编译器中结束运行
        #else
            Application.Quit();//在可执行程序中结束运行
        #endif
    }
    public void LoginClick()//登录按钮
    {
        //先find,tag的效率更高-给input filed的text添加标签
        TMP_Text a = GameObject.FindWithTag("username").GetComponent(); ;//得到两个Text对象
        TMP_Text b = GameObject.FindWithTag("password").GetComponent(); ;//
        Debug.Log("有戏!");
        string username = a.text;
        string password = b.text;
        Debug.Log(username);//纯试出来的
        Debug.Log(password);
        //把账号密码放到一个SocketModel中所定义的类中(其实就是一个结构体)
        LoginDTO dto = new LoginDTO();
        dto.userName = username;
        dto.passWord = password;
        string message = Coding.encode(dto);
        //判断是否为空
        if (username != string.Empty && password != string.Empty)
        {
            //不是发送给服务器,而是利用游戏内部的消息机制 
            Debug.Log("发送消息给MessageManager");
            NetWorkScript.getInstance().sendMessage(0,0,0,message);//这么做主要是为了体验一下unity的消息机制,不能直接用宏名称using不过来
        }
    }
}

你可能感兴趣的:(学习)