unity学习(10)——完成游戏内部消息收发

‘XXX‘ is missing the class attribute ‘ExtensionOfNativeClass‘!_is missing the class attribute 'extensionofnativec-CSDN博客    

        首先明白流程,1 点击按钮->2 RegPanelScript中的LoginClick()->3 NetWorkScript. getInstance(). sendMessage->4 socket.send->5 服务器

        现在主要问题是MessageManager没有参与进来(),内部消息和网络消息完全就是两回事。MessageManager分发游戏内部消息,LoginHandler也是处理游戏内部的消息。

        最后发现LoginClick(),也就是点击按钮要做两件事,既要完成向服务器发送消息,又要游戏内部发送消息巧合的是两种消息都是SocketModel类型的,而且都用的是同一个List,message Manager脚本是通过Update()实现循环处理的,要挂载到canvas上才行。

LoginClick()的代码如下:通过List.Add()实现了游戏内部的消息发送。

1public 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)
    {
        //1不是发送给服务器,而是利用游戏内部的消息机制-button message(message)我不用NGUI罢了
        Debug.Log("发送消息给MessageManager");
        SocketModel temp = new SocketModel();
        temp.type = 0;
        temp.area = 0;
        temp.command = 0;
        temp.message = message;
        NetWorkScript.getInstance().getList().Add(temp);//加入队列等价于发送消息!
        //2下面的才是发送给服务器(network)
        Debug.Log("发送消息给服务器");
        NetWorkScript.getInstance().sendMessage(0,0,0,message);//这么做主要是为了体验一下unity的消息机制,不能直接用宏名称using不过来
        //NetWorkScript.instance.sendMessage(0, 0, 0, message);
    }
}

        MessageManager通过内部消息告诉LoginHandler,后者准备从服务器读取返回的数据包,游戏内部的消息和网络数据包是配合使用的

     读取消息以后,一定要从队列中删除!不然永远循环。

     索性把LoginHandler合到MessageManager中,代码如下

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;//定义
    //public NetWorkScript instance;
    void Start()//初始化时
    {
        //login = GetComponent();//从脚本获得组件,这样是可以的
        //初始化的时候就要把类拿过来!巧了巧了!
        //instance=new NetWorkScript();
    }

    // Update is called once per frame
    void Update()
    {
        //Debug.Log("MessageManager");//这个确实是一直在执行!一秒999的那种
        //Debug.Log("理论上挂载后会一直执行");//的确可以一直执行,很卡
        //从消息队列
        //List list=NetWorkScript.getInstance().getList();//游戏控件消息队列,不涉及网络
        //List list = NetWorkScript.instance.getList();
        List list = NetWorkScript.getInstance().getList();//这么写的目的是实现全局对象,关键是要做到不卡
        //List list = instance.getList();
        for (int i = 0; i < 8; i++)//每帧8条信息
        {
            if (list.Count > 0)
            {
                Debug.Log("MessageManager!!!!!!!!!!!!!!");
                SocketModel model = list[0];//后面有取出信息的
                OnMessage(model);//处理当前的第一条信息
                list.RemoveAt(0);
            }
            else
            {
                break;//无消息跳出循环
            }
        }
    }
    public void OnMessage(SocketModel model)
    {
        //处理当前信息
        switch (model.type)
        {
            case Protocol.LOGIN:
            {
                //Debug.Log("MessageManager一定要参与进来啊!");//成功执行到这里了--成功了!
                LoginHandler(model);//调用的是LoginHandle中的方法--迟早都要删除的
                break;
            }
            case Protocol.USER:
            {
                break;
            }
            case Protocol.MAP:
            {
                break;
            }
            default:
            {
                break;
            }
        }
    }
    //索性不要loginhandler了,把消息处理都写在一个文件夹里
    public void LoginHandler(SocketModel model)
    {
        Debug.Log("这里是LoginHandler.cs 要read了,读取服务器返回的信息");
        //这里是处理游戏内部消息
        //读了就删!
    }
}

Update()中已近删掉了消息,每条消息都是一次性的,程序运行检测无误。

你可能感兴趣的:(网络,服务器,运维)