代码拉取完成,页面将自动刷新
把 src 里面的 protobuf-net 编译或直接放在 unity Assets 中 删掉.csproj 已知问题 proto2 optional和枚举 不能使用,由于ILRuntime不认为ILRT里面跑的数据类型是枚举,导致无法把默认值转换为枚举。
Unity中使用 需要注册一下
static bool InitedILRuntime = false;
static IMethod s_HFInitialize;
static IMethod s_HFUpdate;
static ILRuntime.Runtime.Enviorment.AppDomain HFDomain;
static void InitializeILRuntimeCLR()
{
ProtoBuf.PType.RegisterFunctionCreateInstance(PType_CreateInstance);
ProtoBuf.PType.RegisterFunctionGetRealType(PType_GetRealType);
}
static void Initialize()
{
var hfMain = HFDomain.GetType("HotFix.Main");
s_HFInitialize = hfMain.GetMethod("Initialize", 0);
s_HFUpdate = hfMain.GetMethod("Update", 0);
HFDomain.Invoke(s_HFInitialize, null, null);
}
public static void Update()
{
if (InitedILRuntime)
{
HFDomain.Invoke(s_HFUpdate, null, null);
}
}
static object PType_CreateInstance(string typeName)
{
return HFDomain.Instantiate(typeName);
}
static Type PType_GetRealType(object o)
{
var type = o.GetType();
if (type.FullName == "ILRuntime.Runtime.Intepreter.ILTypeInstance")
{
var ilo = o as ILRuntime.Runtime.Intepreter.ILTypeInstance;
type = ProtoBuf.PType.FindType(ilo.Type.FullName);
}
return type;
}
Dll 中使用 参考 hotfix目录下main.cs
public static void Initialize()
{
ILRuntime_mmopb.Initlize();
Debug.Log("Initialize");
}
public static void Update()
{
if (!s_Initialized) return;
var c = new mmopb.m_login_c();
c.account = new mmopb.p_account_c();
c.account.account = "abc";
c.account.snapshots.Add(new mmopb.p_avatar_snapshot());
c.account.snapshots.Add(new mmopb.p_avatar_snapshot());
var s = new mmopb.p_avatar_snapshot();
s.avatar = new mmopb.p_entity_basis();
s.avatar.account = "defxxx";
c.account.snapshots.Add(s);
c.account.snapshots.Add(s);
var stream = new System.IO.MemoryStream();
ProtoBuf.Serializer.Serialize(stream, c);
Debug.Log(stream.Length);
var bytes = stream.ToArray();
var t = ProtoBuf.Serializer.Deserialize(typeof (mmopb.m_login_c), new System.IO.MemoryStream(bytes)) as mmopb.m_login_c;
Debug.Log(t.account.snapshots.Count);
Debug.Log("Update" + t.account.snapshots[3].avatar.account);
}
增加非反射调用,需要把如下代码放入热更工程,git clone 下来看着就正常了
using ProtoBuf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Helper
{
public sealed class ProtoHelper
{
public static byte[] EncodeWithName(object p)
{
var type = p.GetType();
var name = type.FullName;
using (var ms = new MemoryStream())
{
Serializer.Serialize(ms, p);
//var cos = new Google.Protobuf.CodedOutputStream(ms);
//((IMessage)p).Encode(cos); //非反射方式
//cos.Flush();
var nbs = Encoding.UTF8.GetBytes(name);
int nblen = nbs.Length;
if (nblen > 255)
{
throw new Exception("PB:name->" + name + " is To Long " + nblen + " > 255");
}
var buffer = new byte[ms.Length + nbs.Length + 1];
buffer[0] = (byte)((nblen >> 0) & 0xFF);
Buffer.BlockCopy(nbs, 0, buffer, 1, nblen);
ms.Position = 0;
ms.Read(buffer, 1 + nblen, (int)ms.Length);
return buffer;
}
}
public static object DecodeWithName(byte[] b, out string name)
{
var bytesLen = b[0];
name = Encoding.UTF8.GetString(b, 1, bytesLen);
using (var ms = new MemoryStream(b, 1 + bytesLen, b.Length - 1 - bytesLen))
{
Type T = Type.GetType(name);
if (name.Contains(".")) { name = name.Substring(name.LastIndexOf('.') + 1); }
return Serializer.Deserialize(T, ms);
//var o = Activator.CreateInstance(T);
//((IMessage)o).Decode(new Google.Protobuf.CodedInputStream(ms)); //非反射方式
//return o;
}
}
}
public interface IProtoRecv
{
void OnRecv(string name, object o);
}
public interface IMessage
{
void Encode(Google.Protobuf.CodedOutputStream writer);
void Decode(Google.Protobuf.CodedInputStream reader);
}
}
更新Protobuf-net
枚举是确定不能用的,proto2 optional(optional int32 不支持,optional int64 bool string 可以) (推荐用proto3) src 目录没时间,暂时就不同步了,需要的同学直接拷贝Protobuf目录到U3D就好。
修复对map的支持,现在支持任意map(map<任意类型,任意类型>)。
Mac的同学可以直接使用Protobuf文件夹,把导出的工具做成U3D的Editor了,不需要编译了,导出也比较方便。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。