1.环境搭建
一、Fantasy框架下载1.https://github.com/qq362946/Fantasy.git2.修改 Fantasy/examples/Server/Main/NLog.config 配置打印日志文件:<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"><targets async="true"><target name="ServerDebug" xsi:type="File"encoding="UTF-8"createDirs="true"autoFlush="false"keepFileOpen="true"concurrentWrites="true"openFileCacheTimeout="30"openFileFlushTimeout="60"fileName="${basedir}/../Logs/Server/Server${date:format=yyyyMMdd}/${logger}.${var:appId}.${date:format=yyyyMMddHH}.Debug.log"layout="${longdate} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message}"/></targets><targets async="true"><target name="ServerInfo" xsi:type="File"encoding="UTF-8"createDirs="true"autoFlush="false"keepFileOpen="true"concurrentWrites="true"openFileCacheTimeout="30"openFileFlushTimeout="60"fileName="${basedir}/../Logs/Server/Server${date:format=yyyyMMdd}/${logger}.${var:appId}.${date:format=yyyyMMddHH}.Info.log"layout="${longdate} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message}"/></targets><targets async="true"><target name="ServerWarn" xsi:type="File"encoding="UTF-8"createDirs="true"autoFlush="false"keepFileOpen="true"concurrentWrites="true"openFileCacheTimeout="30"openFileFlushTimeout="60"fileName="${basedir}/../Logs/Server/Server${date:format=yyyyMMdd}/${logger}.${var:appId}.${date:format=yyyyMMddHH}.Warn.log"layout="${longdate} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message}"/></targets><targets async="true"><target name="ServerError" xsi:type="File"encoding="UTF-8"createDirs="true"autoFlush="false"keepFileOpen="true"concurrentWrites="true"openFileCacheTimeout="30"openFileFlushTimeout="60"fileName="${basedir}/../Logs/Server/Server${date:format=yyyyMMdd}/${logger}.${var:appId}.${date:format=yyyyMMddHH}.Error.log"layout="${longdate} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message}"/></targets><targets async="true"><target name="ServerTrace" xsi:type="File"encoding="UTF-8"createDirs="true"autoFlush="false"keepFileOpen="true"concurrentWrites="true"openFileCacheTimeout="30"openFileFlushTimeout="60"fileName="${basedir}/../Logs/Server/Server${date:format=yyyyMMdd}/${logger}.${var:appId}.${date:format=yyyyMMddHH}.Trace.log"layout="${longdate} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message}"/></targets><targets async="true"><target name="ConsoleColor" xsi:type="ColoredConsole"useDefaultRowHighlightingRules="false"layout="${longdate} ${callsite:className=false:methodName=false:fileName=true:includeSourcePath=false:skipFrames=2} ${message}"><highlight-row condition="level == LogLevel.Debug" foregroundColor="DarkGreen" /><highlight-row condition="level == LogLevel.Info" foregroundColor="Gray" /><highlight-row condition="level == LogLevel.Warn" foregroundColor="Yellow" /><highlight-row condition="level == LogLevel.Error" foregroundColor="DarkRed" /><highlight-row condition="level == LogLevel.Fatal" foregroundColor="Red" /></target></targets><rules><!-- 控制台 调试或编辑器启动的时候会调用--><logger ruleName="ConsoleTrace" name="Server" level="Trace" writeTo="ConsoleColor" /><logger ruleName="ConsoleDebug" name="Server" level="Debug" writeTo="ConsoleColor" /><logger ruleName="ConsoleInfo" name="Server" level="Info" writeTo="ConsoleColor" /><logger ruleName="ConsoleWarn" name="Server" level="Warn" writeTo="ConsoleColor" /><logger ruleName="ConsoleError" name="Server" level="Error" writeTo="ConsoleColor" /><!-- 服务端日志输出文件 发布到服务器后会调用--><logger ruleName="ServerDebug" name="Server" level="Debug" writeTo="ServerDebug" /><logger ruleName="ServerTrace" name="Server" level="Trace" writeTo="ServerTrace" /><logger ruleName="ServerInfo" name="Server" level="Info" writeTo="ServerInfo" /><logger ruleName="ServerWarn" name="Server" level="Warn" writeTo="ServerWarn" /><logger ruleName="ServerError" name="Server" level="Error" writeTo="ServerError" /></rules>
</nlog>二、客户端下载1.下载铸梦三件套: https://github.com/ZMteacher/ZMFrameWork2.删除Fantasy下的客户端Fantasy\examples\Client\Unity3.把ZMFrameWork/ZMFrameWork 重命名为 ZMFrameWork/Unity, 放到之前删除的Unity目录 三、修改FantasyZMFrameWorkDemo\Fantasy\.gitignore内容,增加#############其它配置##################!examples/Client/Unity/Assets/ZMPackages/Library四、客户端导入Fantasy框架客户端包Window->Package Manager->Add package from disk->Fantasy\Fantasy.Unity\Fantasy.Unity\package.json五、修改 Client\Unity\Packages\manifest.json下的引用为相对路径"com.fantasy.unity": "file:../../../../Fantasy.Unity/Fantasy.Unity",六、生成前后端协议把 Fantasy\examples\Tools\NetworkProtocol\Run.bat 建立快捷键 协议.bat,放到桌面上,点击生成前后端协议七、服务器导入配置扩展包: Fantasy\Fantasy.Packages\Fantasy.ConfigTable八、生成策划配置Fantasy\examples\Tools\ConfigTable\Run.bat 建立快捷键 Excel.bat, 放到桌面上, 点击生成配置(TODO 目前看客户端配置生成有点问题)九、Main.cs // 客户端入口初始化ZMAssetFrameWork // Awake资源热更 // Start初始化ZMUIFrameWork进入HallWorld弹出LoginWindow登录界面 // SampleScene/GameMain/UIRoot/LoginWindow笔记:各种的初始化顺序的定制:Assets/ZMPackages/ZMGCFrameWork/Runtime/HallWorldScriptExecutionOrder.csPrefabMain下的各种Window快速拖拽模板:Assets\ZMPackages\ZMUI\ThirdLibrary\UGUI-Editor\PrefabsModelAB包路径配置: Assets/ZMPackages/ZMAsset/AssetsPathConfig.cs生成的Prefab的位置: Assets/GameData/Hall/Prefabs/Window生成的脚本的位置:Assets/Scripts/HallWorld
2.客户端常用模块
1.pb和json互转
using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class ProtoBuffConvert
{public static void ToJson<T>(T proto){Debug.Log(typeof(T).Name + JsonConvert.SerializeObject(proto));}public static void PrintRequest<T>(T proto){Debug.Log("->>>" + typeof(T).Name + JsonConvert.SerializeObject(proto));}public static void PrintResponse<T>(T proto){Debug.Log("<<<-" + typeof(T).Name + JsonConvert.SerializeObject(proto));}
}
2.网络模块封装
using System;
using Fantasy;
using Fantasy.Async;
using Fantasy.Network;
using Fantasy.Network.Interface;
using UnityEngine;public class NetworkManager
{private static NetworkManager _instance;public static NetworkManager Instance{get{if (_instance == null){_instance = new NetworkManager();}return _instance;}}private Scene _scene;private Session _session;public async FTask Init(){Fantasy.Platform.Unity.Entry.Initialize(GetType().Assembly);_scene = await Fantasy.Platform.Unity.Entry.CreateScene();Debug.Log("Fantasy Init");}public void Connect(string url, Action successAction = null){Debug.Log($"开始连接服务器url={url}");_session = _scene.Connect(url, //NetworkProtocolType.KCP, // async () =>{Debug.Log($"连接服务器url={url}成功!!!");_session.AddComponent<SessionHeartbeatComponent>().Start(3000);successAction?.Invoke();},() => { Debug.Log($"连接服务器url={url}失败!!!"); }, //() => { Debug.Log($"与服务器url={url} 断开连接!!!"); }, //false, //2000 //);}public void Send<MSG>(IMessage message) where MSG : IMessage{ProtoBuffConvert.PrintRequest((MSG)message);_session.Send(message);}public async FTask<RES> SendCallMessage<REQ, RES>(IRequest request) where REQ : IRequest where RES : IResponse{ProtoBuffConvert.PrintRequest((REQ)request);RES response = (RES)await _session.Call(request);ProtoBuffConvert.PrintResponse(response);return response;}public void Disconnect(){_session.GetComponent<SessionHeartbeatComponent>().Stop();_session.GetComponent<SessionHeartbeatComponent>().Dispose();_session.Dispose();}
}
3.http模块封装
using System;
using System.Collections;
using Fantasy.Async;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Networking;public class HttpManager
{private static HttpManager _instance;public static HttpManager Instance{get{if (_instance == null){_instance = new HttpManager();}return _instance;}}public async FTask<string> Post(string url, object data){UnityWebRequest request = new UnityWebRequest(url, "POST");string jsonData = JsonConvert.SerializeObject(data);request.uploadHandler = new UploadHandlerRaw(System.Text.Encoding.UTF8.GetBytes(jsonData));request.uploadHandler.contentType = "application/json";request.downloadHandler = new DownloadHandlerBuffer();await request.SendWebRequest();if (request.result == UnityWebRequest.Result.Success){return request.downloadHandler.text;}else{return null;}}
}
4.网络和http模块使用
public void OnLoginButtonClick(){string OpenId = dataCompt.AccountIdInputField.text;if (string.IsNullOrEmpty(OpenId)){Debug.LogError("OpenId为空!!!");return;}GetUserIdRequest request = new GetUserIdRequest(){OpenId = OpenId,};Action action = async () =>{string responseJsonData = await HttpManager.Instance.Post(Constant.httpUrl, request);if (responseJsonData == null){Debug.LogError($"httpUrl={Constant.httpUrl}请求错误");return;}GetUserIdResponse response = JsonConvert.DeserializeObject<GetUserIdResponse>(responseJsonData);HallWorld.GetExitsDataMgr<StartDataMgr>().AccountId = response.AccountId;NetworkManager.Instance.Connect(response.GateUrl, async () =>{G2C_LoginResponse g2CLoginResponse = await HallWorld.GetExitsMsgMgr<StartMsgMgr>().SendC2G_LoginRequest();HallWorld.GetExitsDataMgr<StartDataMgr>().DRoleList = g2CLoginResponse.DRoles;// 切换界面UIModule.Instance.DestroyAllWindow();UIModule.Instance.PopUpWindow<HomeWindow>();});};action.Invoke();}