客户端框架的搭建(丛林战争项目)

一、创建一个Unity项目OnlineGameClient并导入资源包


二、项目结构









三、代码

1、Manager包下

①AudioManager

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

public class AudioManager : BaseManager {

    public AudioManager(GameFacade facade) : base(facade) { }
    
}


②BaseManager

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

//不需要继承MonoBehaviour,因为不需要作为组件存在,也不需要start和update方法
public class BaseManager : MonoBehaviour {

    //每个类都包含一个GameFacade的引用,这样子类可以将facade作为中介调用各个manager
    protected GameFacade facade;

    public BaseManager(GameFacade facade)
    {
        this.facade = facade;
    }

    public virtual void OnInit() { }
    public virtual void OnDestroy() { }

}

③CameraManager

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

public class CameraManager : BaseManager {

    public CameraManager(GameFacade facade) : base(facade) { }
}

④PlayerManager

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

public class PlayerManager : BaseManager {

    public PlayerManager(GameFacade facade) : base(facade) { }
}

⑤RequestManager

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

public class RequestManager : BaseManager {

    public RequestManager(GameFacade facade) : base(facade) { }
}


2、Net包下

①ClientManager

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net.Sockets;
using System;
using Common;

//这个是用来管理和服务器端的socket连接
public class ClientManager : BaseManager {

    public const string IP = "127.0.0.1";
    private const int PORT = 6688;
    private Socket clientSocket;
    private Message msg = new Message();


    //创建clientsocket和服务端建立连接
    public override void OnInit()
    {
        base.OnInit();
        clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
        try
        {
            clientSocket.Connect(IP, PORT);
        }
        catch (Exception e)
        {
            Debug.LogWarning("无法连接到服务器端,请检查您的网络!!"+e);
        }
    }

    //开始监听
    private void Start()
    {
        //开始接收
        clientSocket.BeginReceive(msg.Data,msg.StartIndex,msg.RemainSize,SocketFlags.None, ReceiveCallback,null);
    }

    //消息的接收
    private void ReceiveCallback(IAsyncResult ar)
    {
        try
        {
            int count = clientSocket.EndReceive(ar);
            msg.ReadMessage(count, OnProcessDataCallback);
        }
        catch (Exception e)
        {
            Debug.Log(e);
        }
        
    }

    private void OnProcessDataCallback(RequestCode requestCode,string data)
    {

    }

    //发送请求
    public void SendRequest(RequestCode requestCode,ActionCode actionCode,string data)
    {
        //进行数据的打包
        byte[] bytes = Message.PackData(requestCode,actionCode,data);
        //进行数据的发送
        clientSocket.Send(bytes);

    }

    public override void OnDestroy()
    {
        base.OnDestroy();
        try
        {
            clientSocket.Close();
        }
        catch (Exception e)
        {
            Debug.LogWarning("无法关闭跟服务器端的连接!!" + e);
        }
    }

}


②Message

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using Common;
using System.Text;
using System.Linq;

public class Message {
        private byte[] data = new byte[1024];                       //定义一个数组用来存取数据,数组的长度要保证可以存下所有的消息
        private int startIndex = 0;                                 //表示存取了多少个字节的数据在数组里面

        //public void AddCount(int count)                             //提供一个增加数量的方法
        //{
        //    startIndex += count;
        //}

        public byte[] Data                                           //提供一个返回data数组的方法
        {
            get { return data; }
        }

        public int StartIndex
        {
            get { return startIndex; }
        }

        public int RemainSize
        {
            get { return data.Length - startIndex; }                 //剩余的空间
        }

        public void ReadMessage(int newDataAmount, Action<RequestCode, string> processDataCallBack)                                    //解析数据
        {
            startIndex += newDataAmount;
            while (true)
            {
                if (startIndex <= 4)
                    return;
                int count = BitConverter.ToInt32(data, 0);               //获取数据的长度,从索引为0的位置开始读取4个字节
                if (startIndex - 4 >= count)                              //前四个字节是数据的长度,如果减去长度大于数据字节长度,则表示数据可以被完整地保存
                {
                    //string s = Encoding.UTF8.GetString(data,4,count);
                    //Console.WriteLine("解析 :" + s );
                    //Array.Copy(data, count + 4, data, 0, startIndex - 4-count );
                    //startIndex -= (count + 4);

                    //解析RequestCode从4的位置开始解析
                    RequestCode requestCode = (RequestCode)BitConverter.ToInt32(data, 4);
                    //解析ActionCode从8的位置开始解析
                    ActionCode actionCode = (ActionCode)BitConverter.ToInt32(data, 8);
                    //解析数据,从第12个字节开始,数据长度是count-8
                    string s = Encoding.UTF8.GetString(data, 8, count - 4);
                    //解析完成后调用一下回调
                    processDataCallBack(requestCode, s);
                    Array.Copy(data, count + 4, data, 0, startIndex - 4 - count);
                    startIndex -= (count + 4);
                }
                else                                                     //数据不完整
                {
                    break;
                }
            }

        }


        //数据的包装
        public static byte[] PackData(RequestCode requestCode, ActionCode actionCode,string data)
        {
            //requestCode的字节数组
            byte[] requestCodeBytes = BitConverter.GetBytes((int)requestCode);
            //actionCode的字节数组
            byte[] actionCodeBytes = BitConverter.GetBytes((int)actionCode);
            //数据的字节数组
            byte[] dataBytes = Encoding.UTF8.GetBytes(data);
            //requestcode、actioncode和数据的长度
            int dataAmount = requestCodeBytes.Length + dataBytes.Length+ actionCodeBytes.Length;
            //所有长度的字节数组
            byte[] dataAmountBytes = BitConverter.GetBytes(dataAmount);
        //进行组装
        return dataAmountBytes.Concat(requestCodeBytes).ToArray<byte>()
                .Concat(actionCodeBytes).ToArray<byte>()
                .Concat(dataBytes).ToArray<byte>();
        }

    
}


3、Request包下

① BaseRequest

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

public class BaseRequest : MonoBehaviour {

    private RequestCode requestCode = RequestCode.None;

    public virtual void Awake()
    {
        
    }

}


4、Scripts下

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

public class GameFacade : MonoBehaviour {

    private UIManager uiMng;
    private AudioManager audioMng;
    private PlayerManager playerMng;
    private CameraManager cameraMng;
    private RequestManager requestMng;
    private ClientManager clientMng;

	// Use this for initialization
	void Start () {
        InitManager();
	}
	
	// Update is called once per frame
	void Update () {
        DestroyManager();
	}


    //创建和初始化
    private void InitManager()
    {
        uiMng = new UIManager(this);
        audioMng = new AudioManager(this);
        playerMng = new PlayerManager(this);
        cameraMng = new CameraManager(this);
        requestMng = new RequestManager(this);
        clientMng = new ClientManager();

        uiMng.OnInit();
        audioMng.OnInit();
        playerMng.OnInit();
        cameraMng.OnInit();
        requestMng.OnInit();
        clientMng.OnInit();
    }


    private void DestroyManager()
    {
        uiMng.OnDestroy();
        audioMng.OnDestroy();
        playerMng.OnDestroy();
        cameraMng.OnDestroy();
        requestMng.OnDestroy();
        clientMng.OnDestroy();
    }

}






注:

游戏客户端架构


2.使用共享项目的文件

①在共享项目上点击鼠标右键“生成”


②在文件资源管理器中打开文件夹


③在目录G:\games\conglin\use socket tcp to develope games\Common\bin\Debug\netstandard1.4下可以看到Common.dll文件


④然后放到所需要引用的地方


3、错误:Plugin targets .NET 4.x and is marked as compatible with Editor,Editor can oly use assemblies targeting .NET 3.5 or lower,please unselect Editor as compatible platform.


原因:.dll版本太高了,unity只支持3.5版本之下的

解决办法:项目的类库应该选择.NET Framework,目标框架改为2.0以下再重新生成


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值