NetWorkScript 这个脚本中,直接在类的定义中初始化了NetWorkScript对象,为了是实现全局统一使用一个全局类的效果!
NetWorkScript 不能继承 MonoBehaviour,要不里面就不能通过new来创建全局实例了!血的教训。去掉继承就不卡了,原来warming也可以让游戏卡到怀疑人生。
NetWorkScript 继承MonoBehaviour就无法绑定到unity组件上了!不绑了,全局对象实例化以后运行的无比顺滑(内部不断判定instance == null)!
进行消息的分发,最后不同的handler与服务器进行通信。c#的执行效率应该比python高得多。
全局对象的最终代码实现如下
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using Unity.VisualScripting;
using Unity.VisualScripting.FullSerializer;
using UnityEditor.VersionControl;
using UnityEngine;
//using static ByteArray;
public class NetWorkScript
{
private static NetWorkScript instance;//为的就是全局使用同一个对象,这个对象实现消息的队列!开始时就是null
private static Socket socket;
private static string ip = "127.0.0.1";
private static int port = 8083;
private static byte[] buff=new byte[1024];//python是达不到这个效果的 static 隔离且持久
private static List<SocketModel> messageList = new List<SocketModel>();//自定义消息队列
public static NetWorkScript getInstance()//函数
{
if (instance == null)//避免进到这里来--必须在init里面初始化
{
init();
Debug.Log("就怕次次初始化");//说对了!--避过去这个应该就不卡了!这个思维很超前的
}
return instance;
}
public static void init()//这个初始化函数一定要挂到按钮上去,两个按钮!索性就利用Start()函数
{
try
{
Debug.Log("66666666666666我估计这里就没有执行过666666666666666");
instance = new NetWorkScript();//放在这里一次足够了--这里之后就不再是null了
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//一次就应该够用了,毕竟写过python的
socket.Connect(ip, port);
Debug.Log("success");
socket.BeginReceive(buff,0,1024,SocketFlags.None,ReceiveCallBack,buff);//先收再回调
}
catch
{
Debug.Log("网络连接初始化faild");
}
}
public static void 照猫画虎()//这个可是害死我了
{
Debug.Log("2");
init();
Debug.Log("3");
}
void Start()
{
Debug.Log("有Start的类也可以绑在画布上");
init();
}
//sendmessage
public void sendMessage(int type, int area, int command, string message)
{
Debug.Log("先看看到底传过来没");//过来了
Debug.Log(type);
Debug.Log(area);
Debug.Log(command);
Debug.Log(message);
ByteArray arr = new ByteArray();
arr.WriteInt(type);
arr.WriteInt(area);
arr.WriteInt(command);
if (message != null)
{
arr.WriteInt(message.Length);//先长度,再内容
arr.WriteUTFBytes(message);
// arr.WriteUTFBytes(message);
Debug.Log("都写到ByteArray中了");
}
else
{
arr.WriteInt(0);
}
Debug.Log(arr);
try
{
socket.Send(arr.Buffer);//这个是网络的暂时可以错--这里不应该是网络,是游戏内部消息
}
catch
{
Debug.Log("发送socket error");
}
}
private static void ReceiveCallBack( IAsyncResult ar)//回调方法
{
try
{
int readCount = 0;
readCount = socket.EndReceive(ar);//ar其实就是传进来的内容
byte[] temp = new byte[readCount];
Buffer.BlockCopy(buff, 0, temp, 0, readCount);
//再多新建一个
}
catch
{
socket.Close();
Debug.Log("net error");
}
socket.BeginReceive(buff, 0, 1024, SocketFlags.None, ReceiveCallBack, buff);//形成闭环
}
private void readMessage(byte[] message)//处理所收到的信息
{
MemoryStream ms = new MemoryStream(message, 0, message.Length);
ByteArray ba = new ByteArray(ms);//这个模型是自定义的
SocketModel model = new SocketModel();
model.type = ba.ReadInt();
model.area = ba.ReadInt();
model.command = ba.ReadInt();
int length= ba.ReadInt();
if (length>0)
{
model.message = ba.ReadUTFBytes((uint)length);
}
messageList.Add(model);//这个函数也是自定义的
}
public List<SocketModel> getList()
{
return messageList;
}
}