unity学习(9)——全局对象(真正的地狱难度)

         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 messageList = new List();//自定义消息队列

    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 getList()
    {
        return messageList;
    }
}

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