Google protobuf Reflection error with Unity when using il2cpp #5422
What version of protobuf and what language are you using?
Version: v3.6.1
Language: C#
What operating system (Linux, Windows, ...) and version?
MacOS Mojave 10.14
What runtime / compiler are you using (e.g., python version or gcc version)
Apple LLVM version 10.0.0 (clang-1000.11.45.2)
Target: x86_64-apple-darwin18.0.0
Thread model: posix
What did you do?
- Open the following project on Unity 2018.3.0b10 (I think that this happens with any Unity 2018, maybe other years as well)
- Run on the editor to see that the file
Test.cs
executes correctly. - Compile with il2cpp to iOS and run. The code fails with the following stacktrace:
DescriptorValidationException: google.protobuf.Value.kind: Method ClearKind not found in Google.Protobuf.WellKnownTypes.Value
at Google.Protobuf.Reflection.OneofDescriptor.CreateAccessor (System.String clrName) [0x00000] in <00000000000000000000000000000000>:0
at Google.Protobuf.Reflection.OneofDescriptor..ctor (Google.Protobuf.Reflection.OneofDescriptorProto proto, Google.Protobuf.Reflection.FileDescriptor file, Google.Protobuf.Reflection.MessageDescriptor parent, System.Int32 index, System.String clrName) [0x00000] in <00000000000000000000000000000000>:0
at Google.Protobuf.Reflection.MessageDescriptor+<>c__DisplayClass4_0.<.ctor>b__0 (Google.Protobuf.Reflection.OneofDescriptorProto oneof, System.Int32 index) [0x00000] in <00000000000000000000000000000000>:0
at Google.Protobuf.Reflection.DescriptorUtil.ConvertAndMakeReadOnly[TInput,TOutput] (System.Collections.Generic.IList`1[T] input, Google.Protobuf.Reflection.DescriptorUtil+IndexedConverter`2[TInput,TOutput] converter) [0x00000] in <00000000000000000000000000000000>:0
at Google.Protobuf.Reflection.MessageDescriptor..ctor (Google.Protobuf.Reflection.DescriptorProto proto, Google.Protobuf.Reflection.FileDescriptor file, Google.Protobuf.Reflection.MessageDescriptor parent, System.Int32 typeIndex, Google.Protobuf.Reflection.GeneratedClrTypeInfo generatedCodeInfo) [0x00000] in <00000000000000000000000000000000>:0
at Google.Protobuf.Reflection.FileDescriptor+<>c__DisplayClass1_0.<.ctor>b__0 (Google.Protobuf.Reflection.DescriptorProto message, System.Int32 index) [0x00000] in <00000000000000000000000000000000>:0
at Google.Protobuf.Reflection.DescriptorUtil.ConvertAndMakeReadOnly[TInput,TOutput] (System.Collections.Generic.IList`1[T] input, Google.Protobuf.Reflection.DescriptorUtil+IndexedConverter`2[TInput,TOutput] converter) [0x00000] in <00000000000000000000000000000000>:0
at Google.Protobuf.Reflection.FileDescriptor..ctor (Google.Protobuf.ByteString descriptorData, Google.Protobuf.Reflection.FileDescriptorProto proto, Google.Protobuf.Reflection.FileDescriptor[] dependencies, Google.Protobuf.Reflection.DescriptorPool pool, System.Boolean allowUnknownDependencies, Google.Protobuf.Reflection.GeneratedClrTypeInfo generatedCodeInfo) [0x00000] in <00000000000000000000000000000000>:0
at Google.Protobuf.Reflection.FileDescriptor.BuildFrom (Google.Protobuf.ByteString descriptorData, Google.Protobuf.Reflection.FileDescriptorProto proto, Google.Protobuf.Reflection.FileDescriptor[] dependencies, System.Boolean allowUnknownDependencies, Google.Protobuf.Reflection.GeneratedClrTypeInfo generatedCodeInfo) [0x00000] in <00000000000000000000000000000000>:0
at Google.Protobuf.Reflection.FileDescriptor.FromGeneratedCode (System.Byte[] descriptorData, Google.Protobuf.Reflection.FileDescriptor[] dependencies, Google.Protobuf.Reflection.GeneratedClrTypeInfo generatedCodeInfo) [0x00000] in <00000000000000000000000000000000>:0
at Google.Protobuf.WellKnownTypes.StructReflection..cctor () [0x00000] in <00000000000000000000000000000000>:0
at Google.Protobuf.WellKnownTypes.Value.get_Descriptor () [0x00000] in <00000000000000000000000000000000>:0
at Google.Protobuf.JsonParser..cctor () [0x00000] in <00000000000000000000000000000000>:0
at Test.Start () [0x00000] in <00000000000000000000000000000000>:0
Rethrow as ArgumentException: Invalid embedded descriptor for "google/protobuf/struct.proto".
at Google.Protobuf.Reflection.FileDescriptor.FromGeneratedCode (System.Byte[] descriptorData, Google.Protobuf.Reflection.FileDescriptor[] dependencies, Google.Protobuf.Reflection.GeneratedClrTypeInfo generatedCodeInfo) [0x00000] in <00000000000000000000000000000000>:0
at Google.Protobuf.WellKnownTypes.StructReflection..cctor () [0x00000] in <00000000000000000000000000000000>:0
at Google.Protobuf.WellKnownTypes.Value.get_Descriptor () [0x00000] in <00000000000000000000000000000000>:0
at Google.Protobuf.JsonParser..cctor () [0x00000] in <00000000000000000000000000000000>:0
at Test.Start () [0x00000] in <00000000000000000000000000000000>:0
Rethrow as TypeInitializationException: The type initializer for 'Google.Protobuf.WellKnownTypes.StructReflection' threw an exception.
at Google.Protobuf.WellKnownTypes.Value.get_Descriptor () [0x00000] in <00000000000000000000000000000000>:0
at Google.Protobuf.JsonParser..cctor () [0x00000] in <00000000000000000000000000000000>:0
at Test.Start () [0x00000] in <00000000000000000000000000000000>:0
Rethrow as TypeInitializationException: The type initializer for 'Google.Protobuf.JsonParser' threw an exception.
at Test.Start () [0x00000] in <00000000000000000000000000000000>:0
(Filename: currently not available on il2cpp Line: -1)
解决方法:
The problem here is that part of the Google.Protobuf.dll assembly which is used only via reflection is removed by the Unity managed bytecode stripping process. For IL2CPP, Unity always enables managed bytecode stripping, so you will need to indicate that the Google.Protobuf.dll assembly should not be modified.
This is possible by placing a link.xml file in the Assets/ folder of the project with the following content:
<linker>
<assembly fullname="Google.Protobuf" preserve="all"/>
</linker>
You can find out more information about the link.xml file here: https://docs.unity3d.com/Manual/IL2CPP-BytecodeStripping.html
//解决NavMesh导航时转弯速度很慢///
在Nav Mesh Agent组件上Angular Speed可以控制AI转弯的角速度,然而经过测试,将参数设置为360度转弯的速度也是比较慢,更大的话跟360度也没有区别
Unity官方API文档介绍:实际的角速度还受到AI接近时的速度以及最大加速度的影响,通常的做法是通过代码自行控制旋转:设置AngularSpeed为0或代码设置NavMeshAgent的属性updateRotation为false
//
解决“SetDestination“ can only be called on an active agent that has been placed on a NavMesh
游戏运行后使用Instantiate方式将实例化物体,再改变其初始位置,使得物体在实例化的一瞬间距离导航网格过远,使得导航失效
GameObject go = Instantiate(prefab);
go.transform.position = new Vector3(1, 2, 3);
解决方法:1、在实例化的同时设置位置GameObject go = Instantiate(prefab, new Vector3(1, 2, 3), Quaternion.identity);
2、将物体身上的导航组件先关闭,在设置好位置后在开启
3、判断物体是否在导航网格上,如果不在就纠正位置
if(agent.isOnNavMesh)
{
agent.Warp(pos);
}
//
Assertion failed on expression: 'gOnDemandAssets->empty() || GetOnDemandModeV2() != AssetDatabase::OnDemandMode::Off' UnityEditor.EditorApplication:ExecuteMenuItem(String)
编辑器的报错,日志重定向,双击的时候就会出现这个错误
Assertion failed on expression:"m_CurrentEntriesPtr != NULL && m_IsGettingEntries"
UnityEditorInternal.LogEntries:GetEntryInternal(Int32, LogEntry)
UnityEditor.DockArea:OnGUI()
要解决先要定位到具体的代码,然后将这行代码延时执行,延时的时间是到编辑器GUI更新完后,unity中有对应的回调,把代码放到回调中执行即可。比如日志重定向对应的修改到如下:
EditorApplication.delayCall = delegate(){ AssetDatabase.OpenAsset(obj, line); };
/
Mesh buffers are 16 bit by default. See Mesh-indexFormat:
Index buffer can either be 16 bit (supports up to 65535 vertices in a mesh), or 32 bit (supports up to 4 billion vertices). Default index format is 16 bit, since that takes less memory and bandwidth.
Without looking too closely at the rest of your code, I do note that you've not set a 32 bit buffer. Try:
mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
Format of the mesh index buffer data.
Index buffer can either be 16 bit (supports up to 65535 vertices in a mesh), or 32 bit (supports up to 4 billion vertices). Default index format is 16 bit, since that takes less memory and bandwidth.
Note that GPU support for 32 bit indices is not guaranteed on all platforms; for example Android devices with Mali-400 GPU do not support them. When using 32 bit indices on such a platform, a warning message will be logged and mesh will not render.
Changing indexFormat sets subMeshCount to one and clears the index buffer.
See Also: IndexFormat, ModelImporter.indexFormat, SetIndices, SetTriangles, SetIndexBufferParams, SetIndexBufferData.
The number of sub-meshes inside the Mesh object.
Each sub-mesh corresponds to a Material in a Renderer, such as MeshRenderer or SkinnedMeshRenderer. A sub-mesh consists of a list of triangles, which refer to a set of vertices. Vertices can be shared between multiple sub-meshes.
See Also: GetTriangles, SetTriangles.
For advanced lower-level sub-mesh and mesh data manipulation functions, see SubMeshDescriptor, SetSubMesh, SetIndexBufferParams, SetIndexBufferData.
Note that changing subMeshCount to a smaller value than it was previously resizes the Mesh index buffer to be smaller. The new index buffer size is set to SubMeshDescriptor.indexStart of the first removed sub-mesh.
一个批次的顶点数在2~3万左右,大概7~8个批次
我是不是可以理解为一个FBO有大概8个draw,每个draw的vertex数目是2-3万?
Mali GPU是tile-based GPU,所以在运行过程中会为shader中出现的varying分配memory,假设一个shader的vertex shader用到了4个vec4 varying输出,那么一个FBO所需要的memory大概是30000 * 8(8个draw) * 4(4个vec4) * 4(1个vec4是4个float) * sizeof(float) = 15360000 bytes = 14.65M bytes.
因为GPU是按照pipeline执行的,假设同时有3个FBO可以同时运行,那么运行你这个app所需要的memory就是14.65M * 3 ~ 44M。
这是一个不小的数字,在老的手机上很可能会导致out of memory。
memory大概是9000 * 1(1个draw) * 1(1个vec4) * 4(1个vec4是4个float) * sizeof(float) = 144000 bytes = 140.625K bytes.
/
I'v tryed to combine the skinned meshes today.
I can combine all the skinned meshes to one now.And they looks like at the right position and with the right uvs. However , It's just a static mesh,it can not do any animation.I checked the API of Unity, I found that ,mybe it is not possible to combine all meshes with animation. The reseaon is here:
- Every mesh has huge vertices and boneWeights , one boneWeight per one vertex.The boneWeight contains up to 4 indexes and weights relative to the bindPose list.
- The bindPose list is a array of Matrixes , every Matrix means a trasformation relative to the skinned-mesh's rootBone.
- The boneWeights are just used as weight-calculation of up to 4 bindPose matrixes , the result is one average matrix relative to the skinned-mesh's rootBone.
At last , we can think out the calculation process of the vertex's position.
vertex world transformation <= weight-calculated matrix to the rootBone <= rootBone's transformation is animated by the animation
This is the relation process. Then, for example, one animation contains 5 bones, and 7 skinned-meshes , the 7 skinned-meshes are relative to diffrent bones, even we've combined the meshes ,we just got the static mesh, one mesh can't rely on 5 rootBones, so it lost the animation feature.
So, I think maybe it is the result: we only can get the static mesh , with no animation.
I'm glad to tell you that the baking does work now.And all problems are resolved.
I think there are 4 key points:
1、The rootBone is not important ,even maybe it is not need.
2、All mesh points all calculated relative to the bones,and when using the Unity's Combination,it combine all the bones together to a new big bones set.
So, every thing is ok,bones are still work.
3、We juse need to collect all the bones in original skinned-meshes,and give the array of bones to the new created Skinned-Mesh(set the bones).
4、Before do out combination, we need to set all skinned-meshes to standard state (with no scal,tranlate or rotate), and move the animation node to world center, with no scal and rotation, then do the combination,when finished,we can take the animation node back to old state.
That's it. I think it works now. I will update my plug-in tomorrow.
/
/
KeyguardManager keyguardManager = (KeyguardManager)getSystemService(Activity.KEYGUARD_SERVICE);
KeyguardManager.KeyguardLock lock = keyguardManager.newKeyguardLock(KEYGUARD_SERVICE);
lock.disableKeyguard(); //关闭系统锁屏
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
//
Camer的Allow MSAA和一些粒子的FrameDebug的检测下,有可能花屏的处理
UnityEditor.AsyncHTTPClient:Done(State, Int32)
Thisusually happens when there is a problem with Unity's Asset server.
You cantemporray disable that error by going to:
Edit --> Preferences... --> thendisable Show Asset Store search hits.
lock (DataLocker)
{
List<int> lst = null;
inta = lst.Count;
}
在UDP接收,不会抛出异常,但是逻辑不对,需要自己手动trycatch
//PrefabEvolution 插件的EvolvePrefab 脚本引用错误
Prefab asset script is missing. Prefab has areference to prefab asset, that must have attached PrefabScript. AssetGUID:8db184356d91efe4880310c0dae82ff1,AssetPath:Assets/Art/Enviroment/DemoScene/Build/Prefabs/B_jisi_building11_c.prefabPrefabPath:Assets/Resources/ArtResources/Scene/LostIsland.unity
UnityEngine.Debug:LogErrorFormat(Object,String, Object[])
Debug:LogErrorFormat(Object, String,Object[]) (at Assets/Scripts/Utils/Debug.cs:52)
PrefabEvolution.PEPrefabScriptExt:CheckPrefab(PEPrefabScript)(at Assets/PrefabEvolution/Sources/Editor/PEPrefabScriptExt.cs:53)
PrefabEvolution.PEPrefabScriptExt:OnValidate(PEPrefabScript)(at Assets/PrefabEvolution/Sources/Editor/PEPrefabScriptExt.cs:21)
PrefabEvolution.PEPrefabScript:OnValidate()(at Assets/PrefabEvolution/Sources/PEPrefabScript.cs:68)
UnityEditor.DockArea:OnGUI()
//解决方法:把场景里EvolvePrefab引用删除,工程里EvolvePrefab引用也对应删除。否则两边不匹配场景里有,工程里没有就在PrefabEvolution的OnValidate 检查出错。
Script attached to 'prefab_Name' inscene '' is missing or no valid script is attached.
UnityEditor.BuildPipeline:BuildPlayerInternalNoCheck(String[],String, String, BuildTargetGroup, BuildTarget, BuildOptions, Boolean)
UnityEditor.BuildPipeline:BuildPlayerInternal(String[],String, String, BuildTargetGroup, BuildTarget, BuildOptions) (atC:\buildslave\unity\build\artifacts\generated\common\editor\BuildPipelineBindings.gen.cs:310)
UnityEditor.BuildPipeline:BuildPlayer(String[],String, String, BuildTargetGroup, BuildTarget, BuildOptions) (atC:\buildslave\unity\build\artifacts\generated\common\editor\BuildPipelineBindings.gen.cs:244)
UnityEditor.BuildPipeline:BuildPlayer(BuildPlayerOptions)(atC:\buildslave\unity\build\artifacts\generated\common\editor\BuildPipelineBindings.gen.cs:207)
UnityEditor.BuildPipeline:BuildPlayer(String[],String, BuildTarget, BuildOptions) (atC:\buildslave\unity\build\artifacts\generated\common\editor\BuildPipelineBindings.gen.cs:201)
BuildEditor:GenericBuild(String[], String,BuildTargetGroup, BuildTarget, BuildOptions) (atAssets\Editor\BuildEditor.cs:632)
BuildEditor:PCBuild(Boolean,String) (at Assets\Editor\BuildEditor.cs:503)
///
Resource ID out of range in GetResource: 1080000 (max is 1000000)
Resource ID out of range in GetResource: 1048576 (max is 1048575)
(Filename: ./Runtime/GfxDevice/GfxResourceIDMap.h Line: 109)
I am using the post processing stack in my project (v 2.1.7), but I am not using any SSR.
I have remotely profiled my game with both the Profiler and the experimental Memory Profiler and do not see any allocated memory growing over the course of 2-3 hours (These crashes usually happen when the game is left running overnight).
I have tried to recreate this issue in a simpler project to my game so that I can submit a bug report but cannot reproduce the issue.
tempRenderTexture = RenderTexture.GetTemporary(texture.width, texture.height, 0, RenderTextureFormat.Default,RenderTextureReadWrite.Linear);
Graphics.Blit(texture, tempRenderTexture);
tempTexture2d.ReadPixels(new Rect(0, 0, tempRenderTexture.width, tempRenderTexture.height), 0, 0);
after use it,i try to release use code tempRenderTexture.Release();
then it cause the error "Resource ID out of range in GetResource" after about 3 hours running
I fixed it use code RenderTexture.ReleaseTemporary(tempRenderTexture);
it turns out that "Release()" is broken for temporary RT's, and you must NOT use it. Instead, you need to use the static "ReleaseTemporary( x )" method.
This kind-of makes sense - Unity is doing some resource-sharing behind the scenes managed at the static/class level - but it violates some basic expectations of texture operations I had from years of working with low-level textures ("always remember to call release()" and "release() works or throws errors if it fails [it doesnt throw errors, sadly ]"), so I'm suspicious this counts as a bug.
///