Я начал создавать игру Unity как проект Visual Studio. Я создал побочный проект (WinForms) для тестирования, поскольку я не знаю модульного тестирования. Там весь мой код работает отлично, класс сериализации работает безупречно, даже когда используемая протобуф-сеть DLL является единственной для Unity. Теперь, когда я начал работать в Unity, я скопировал все свои коды и DLL для protobuf-net и MySQL.Data. По какой-то причине я не могу заставить (в принципе) использовать тот же код. Я всегда получаю исключение при десериализацией, в основном это:не удалось де-сериализовать данные
Недопустимое поле в источнике данных: 0
И это
Неожиданный конец группы в исходных данных; это обычно означает, что источник данных поврежден
Это трассировки стека для последнего исключения:
ProtoBuf.ProtoException: Неожиданный конец группы в исходных данных; это обычно означает, что источник данные повреждены на ProtoBuf.ProtoReader.ReadFieldHeader() при (оберточной динамической-методе) NeohumanSoftware.AoN.UserInformation.User.proto_2 (объект, ProtoBuf.ProtoReader) в ProtoBuf.Serializers.CompiledSerializer.ProtoBuf .Serializers.IProtoSerializer.Read (объект, ProtoBuf.ProtoReader) at ProtoBuf.Meta.RuntimeTypeModel.Deserialize (int, object, ProtoBuf.ProtoReader) at ProtoBuf.Meta.TypeModel.DeserializeCore (ProtoBuf.ProtoReader, System.Type, object , bool) at ProtoBuf.Meta.TypeModel.Deserialize (System.IO.Stream, object, System.Type, ProtoBuf.SerializationContext) at ProtoBuf.Meta.TypeModel.Deserialize (System.IO.Stream, object, System.Type) на ProtoBuf.Serializer.Deserialize (System.IO.Stream) < 0x000ae> в NeohumanSoftware.AoN.Storage.SerializationHandler.DeSerialize (строка) < 0x00140> в NeohumanSoftware.AoN.Storage.DataHandler.DeserializeUser (строка)
Я опустил последнюю часть трассировки стека как это не имеет значения. Я не понимаю, почему он работает в Visual Studio, но не в Unity. Это сериализатор:
using (MemoryStream ms = new MemoryStream())
{
Serializer.Serialize(ms, ToSerialize);
return ms.ToArray();
}
И это де-сериализатор:
using (MemoryStream ms = new MemoryStream(ToDeSerialize))
{
return Serializer.Deserialize<T>(ms);
}
И это объект для сериализации, который является «сердцем» игр, как все идет от User.user :
[ProtoContract]
internal class User
{
internal static User user { get; set; }
[ProtoMember(1)]
internal Something uSomething { get; private set; }
[ProtoMember(2)]
internal bool uSomething2 { get; set; }
[ProtoMember(3)]
internal Something3 uSomething3 { get; set; }
[ProtoMember(4)]
internal Something4 uSomething4 { get; private set; }
[ProtoMember(5)]
internal Something5 uSomething5 { get; private set; }
Все эти пользовательские классы имеют [ProtoContract] атрибут вместе с, по меньшей мере, один [ProtoMember], и я не использую любой другой атрибут, кроме этих 2. это поток игры:
- Данные создаются.
- Данные сериализованы.
- Сериализованные данные передаются для шифрования (RijndaelManaged).
- Зашифрованные и сериализованные данные записываются в файл.
- Окончание игр
- Данные загружаются из файла.
- Данные не зашифрованы с использованием тех же ключей и IV (случайно сгенерированных и сохраненных)
- Данные де-сериализованы.
- Игра начинается
EDIT: Попытка использовать проект Visual Studio для десериализации данных Юнити делает НЕ работы. Попытка использовать Unity для де-сериализации данных Visual Studio делает NOT работы. Похоже, что Unity не нравится Protobuf-сеть на всех ...
EDIT2: Я изменил метод сериализатора на:
byte[] b;
using (MemoryStream ms = new MemoryStream())
{
Serializer.Serialize(ms, toXML);
b = new byte[ms.Position];
var fullB = ms.GetBuffer();
Array.Copy(fullB, b, b.Length);
}
И это то, что я получил:
Protobuf .ProtoException: недопустимый тип проводки; это обычно означает, что вы переписан файл без усечения или установки длины; см Using Protobuf-net, I suddenly got an exception about an unknown wire-type на ProtoBuf.ProtoReader.SkipField() при (оберточной динамической-методе) NeohumanSoftware.AoN.UserInformation.User.proto_2 (объект, ProtoBuf.ProtoReader) в ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read (объект, ProtoBuf.ProtoReader) в ProtoBuf.Meta.RuntimeTypeModel.Deserialize (INT, объект, ProtoBuf.ProtoReader) в ProtoBuf.Meta.TypeModel.DeserializeCore (ProtoBuf.ProtoReader, System.Type, объект, BOOL) в Protobuf .TypeModel.Deserialize (System.IO.Stream, object, System.Type, ProtoBuf.SerializationContext) на ProtoBuf.Meta.TypeModel.Deserialize (System.IO.Stream, object, System.Type) на ProtoBuf.Serializer .Deserialize (System.IO.Stream) < 0x000ae>
Если это помогает, это чтение и запись в файл методы:
internal static void SaveUser(string userSerialized)
{
File.WriteAllText(SomePath, userSerialized);
}
internal static void LoadUser(string userSerialized)
{
File.ReadAllText(SomePath);
}
EDIT 3: В проекте Unity, я имел это, что у меня не было в проекте Visual Studio,:
internal static Coordinates FromVector3(Vector3 vector)
{
return new Coordinates(vector.x, vector.y, vector.z);
}
internal static Vector3 ToVector3(Coordinates c)
{
return new Vector3(c.X, c.Y, c.Z);
}
Они находятся в классе Координаты, который имеет [ProtoContract] и [ProtoMember] для X, Y и Z. Комментирование этих двух методов не позволяет мне получать исключения, но сериализация все еще не работает (Пользователь свойства являются «новыми»)
Вы уверены, что не используете 'GetBuffer()' где-нибудь? Ведущей причиной «Недопустимое поле в исходных данных: 0» является 'GetBuffer()' (обратите внимание: в 'GetBuffer()' ничего не происходит неправильно, если вы помните только о первых байтах 'Length') –
@MarcGravell да, я абсолютно уверен, что не использую GetBuffer(). Я использовал его, но изменил его на ToArray(), когда я впервые получил эту проблему несколько недель назад. –