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<LoginHandler>();//从脚本获得组件,这样是可以的
}
// Update is called once per frame
void Update()
{
//从消息队列
List<SocketModel> 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<SocketModel> 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<T>
{
public static string encode(T model)
{
return JsonMapper.ToJson(model);
}
public static T decode(string message)
{
return JsonMapper.ToObject<T>(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<TMP_Text>(); ;//得到两个Text对象
TMP_Text b = GameObject.FindWithTag("password").GetComponent<TMP_Text>(); ;//
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<LoginDTO>.encode(dto);
//判断是否为空
if (username != string.Empty && password != string.Empty)
{
//不是发送给服务器,而是利用游戏内部的消息机制
Debug.Log("发送消息给MessageManager");
NetWorkScript.getInstance().sendMessage(0,0,0,message);//这么做主要是为了体验一下unity的消息机制,不能直接用宏名称using不过来
}
}
}