/** * 递归获取一段资源列表的所有依赖资源 */ private void GetAllDependenciesList( ref List <string> allDependenciesList, // 最终结果 List <string> resources // 要记入的资源 ) { //Debug.Log("GetAllDependenciesList" + allDependenciesList.ToArray().Length); foreach (string resourcePath in resources) { JSONObject resourceStorage = storage.GetField(resourcePath); if (resourceStorage == null) { Debug.LogError("创建资源包时写入'" + resourcePath + "'失败,没有找到该资源的转换记录"); continue; } List <string> dependencies = WXUtility.ConvertJSONArrayToList( resourceStorage.GetField("dependencies") ); if (dependencies != null && dependencies.ToArray().Length > 0) { GetAllDependenciesList(ref allDependenciesList, dependencies); // 排重后add入 foreach (string dependency in dependencies) { if (!allDependenciesList.Contains(dependency)) { allDependenciesList.Add(dependency); } } } // 加入它本身 if (!allDependenciesList.Contains(resourcePath)) { allDependenciesList.Add(resourcePath); } } }
private static bool CheckCacheFileCompletion() { if (storage == null) { ErrorUtil.ExportErrorReporter .create() .error(0, "导出缓存还未初始化,请先打开一次导出面板或调用BeefBall.DoInstallationCheck()"); } List <string> assetsMD5 = new List <string>(); JSONObject files = storage.GetField("files"); for (int i = 0; i < files.Count; i++) { string resPath = files.keys[i]; assetsMD5.Add(files.GetField(resPath).GetField("MD5").GetRawString()); } string[] filePaths = Directory.GetFiles(GetContentFolderPath()); List <string> fileNames = new List <string>(); for (int i = 0; i < filePaths.Length; i++) { string path = filePaths[i]; int lastBar = path.LastIndexOf('/'); fileNames.Add(path.Substring(lastBar + 1, path.Length - lastBar - 1)); } for (int i = 0; i < assetsMD5.Count; i++) { if (!fileNames.Contains(assetsMD5[i])) { return(false); } } return(true); }
private void writeResourceRecursive(string resourceDescriptionFilePath) { // 如果已经转换过了 if (packageGroupManifest_resourceDefinitions.HasField(resourceDescriptionFilePath)) { return; } // 先找到之前已经写入缓存表的资源。 JSONObject resourceStorage = storage.GetField("assets").GetField(resourceDescriptionFilePath); if (resourceStorage == null) { Debug.LogError("创建资源包时写入'" + resourceDescriptionFilePath + "'失败,没有找到该资源的转换记录"); return; } // 创建每一个资源definition的json对象 JSONObject definitionObject = new JSONObject(JSONObject.Type.OBJECT); packageGroupManifest_resourceDefinitions.AddField(resourceDescriptionFilePath, definitionObject); // 写入字段 definitionObject.AddField("dependencies", resourceStorage.GetField("dependencies")); definitionObject.AddField("type", resourceStorage.GetField("type")); definitionObject.AddField("descriptionFileID", resourceDescriptionFilePath); // 把记在缓存里的useFile拿出来,遍历,写入group.manifest.json的fileDescription字段 // 并且排除掉resourceDescriptionFilePath之后放入resourceDefinition JSONObject outputUseFileArray = new JSONObject(JSONObject.Type.ARRAY); definitionObject.AddField("useFile", outputUseFileArray); // 放入文件 foreach (string usingFile in WXUtility.ConvertJSONArrayToList(resourceStorage.GetField("useFile"))) { if (usingFile != resourceDescriptionFilePath) { outputUseFileArray.Add(usingFile); } if (packageGroupManifest_fileDescription.HasField(usingFile)) { continue; } JSONObject fileStorage = storage.GetField("files").GetField(usingFile); // add fileDescriptions JSONObject fileDescription = new JSONObject(JSONObject.Type.OBJECT); packageGroupManifest_fileDescription.AddField(usingFile, fileDescription); fileDescription.AddField("path", usingFile); // add files 555 JSONObject fileItem = new JSONObject(JSONObject.Type.OBJECT); fileItem.AddField("path", usingFile); fileItem.AddField("filetype", fileStorage.GetField("filetype")); packageGroupManifest_files.Add(fileItem); wxFileUtil.CopyFile( Path.Combine(storagePath, Path.Combine(CONTENT_FOLDER, fileStorage.GetField("MD5").GetRawString())), Path.Combine(destPath, usingFile) ); } // 递归转依赖 foreach (string dependencyResource in WXUtility.ConvertJSONArrayToList(resourceStorage.GetField("dependencies"))) { writeResourceRecursive(dependencyResource); } }
protected override JSONObject ToJSON(WXHierarchyContext context) { JSONObject json = new JSONObject(JSONObject.Type.OBJECT); JSONObject data = new JSONObject(JSONObject.Type.OBJECT); JSONObject lodList = new JSONObject(JSONObject.Type.ARRAY); json.AddField("type", getTypeName()); json.AddField("data", data); data.AddField("active", lodGroup.enabled); data.AddField("lodCount", lodGroup.lodCount); float radius = 0f; JSONObject center = new JSONObject(JSONObject.Type.OBJECT); center.AddField("x", 0); center.AddField("y", 0); center.AddField("z", 0); LOD[] lods = lodGroup.GetLODs(); int lodIndex = 0; int radiusCountIndex = 0; string matchedRenderer = ""; foreach (LOD lod in lods) { JSONObject lodObject = new JSONObject(JSONObject.Type.OBJECT); JSONObject rendererList = new JSONObject(JSONObject.Type.ARRAY); lodObject.AddField("screenRelativeTransitionHeight", lod.screenRelativeTransitionHeight); lodObject.AddField("fadeTransitionWidth", lod.fadeTransitionWidth); Renderer[] renderers = lod.renderers; int renderersCount = renderers.Length; int rendererIndex = 0; foreach (Renderer renderer in renderers) { string targetRenderer = HandleRenderer(rendererList, renderer, context); /* 计算LODGroup包围球面积的逻辑: * 1. 如果当前的半径是0,说明一直未得到合法的Mesh半径信息,(比如当前LOD里就没有添加Renderer),说明需要进行一次计算 * 2. 如果当前半径不是0,需要分两种情况讨论 * 2.1. 如果当前的rendererIndex为0,说明是新的一轮LOD遍历,说明此前已经计算出了radius了,已经不用再进行计算了 * 2.2. 如果当前的rendererIndex不为0,且半径也有值,需要判断一下这个值是否是当前轮次计算出来的,如果是的话,也需要继续计算取最大值;如果是上一轮次计算出来的,那么就不需要继续计算了。 */ if ( radius == 0f || (rendererIndex != 0 && (radiusCountIndex == lodIndex)) ) { JSONObject tempBoundingBall = HandleRendererCapsuleBoundingBall(renderer); float tempRadius = tempBoundingBall.GetField("radius").n; if (tempRadius > radius) { radius = tempRadius; center = tempBoundingBall.GetField("center"); matchedRenderer = targetRenderer; } radiusCountIndex = lodIndex; } rendererIndex++; } lodObject.AddField("renderers", rendererList); lodList.Add(lodObject); lodIndex++; } data.AddField("lodList", lodList); data.AddField("radius", radius); data.AddField("center", center); data.AddField("renderer", matchedRenderer); return(json); }
public JSONObject ToJSON() { // 创建json对象 JSONObject json = new JSONObject(JSONObject.Type.OBJECT); json.AddField("name", name); if (isPrefabNodeInParentInstance) { json.AddField("__type", "prefabNode"); json.AddField("__prefab", prefabPath); } if (isNestedPrefabRoot) { json.AddField("__type", "nestedPrefabRoot"); json.AddField("__prefab", prefabPath); json.AddField("__prefabInstanceFileId", prefabRootInstanceFileId.ToString()); } if (isOutermostPrefabRoot) { json.AddField("__type", "outermostPrefabRoot"); json.AddField("__prefab", prefabPath); json.AddField("__prefabInstanceFileId", prefabRootInstanceFileId.ToString()); } json.AddField("__fileId", fileIdInOriginalSource.ToString()); if (children.Count > 0) { // 如果有一个子元素,就创建json数组 JSONObject childrenArray = new JSONObject(JSONObject.Type.ARRAY); foreach (WXEntity go in children) { childrenArray.Add(go.arrayId); } json.AddField("children", childrenArray); } if (components.Count > 0) { JSONObject componentsArray = new JSONObject(JSONObject.Type.ARRAY); foreach (int comp in components) { componentsArray.Add(comp); } json.AddField("components", componentsArray); } JSONObject data = json.GetField("data"); if (data != null) { data.AddField("active", active); data.AddField("layer", gameObject == null ? 0 : gameObject.layer); } else { JSONObject newData = new JSONObject(JSONObject.Type.OBJECT); newData.AddField("active", active); newData.AddField("layer", gameObject == null ? 0 : gameObject.layer); json.AddField("data", newData); } //if (isExtraEntity && !isNguiChild) //{ // json = new JSONObject(JSONObject.Type.BAKED); //} return(json); }
private byte[] WriteMeshFile(ref JSONObject metadata) { MemoryStream fileStream = new MemoryStream(); //ushort subMeshCount = (ushort)mesh.subMeshCount; string item = meshName; // 分析vertexLayout WXMeshVertexLayout vertexLayout = new WXMeshVertexLayout(mesh); List <Transform> bones = new List <Transform>(); for (int j = 0; j < renderer.bones.Length; j++) { Transform item2 = renderer.bones[j]; if (bones.IndexOf(item2) == -1) { bones.Add(item2); } } //List<VertexData> vertexDatas = new List<VertexData>(); //List<VertexData> boneGroupVertex = new List<VertexData>(); //List<VertexData> vertexDataQueue = new List<VertexData>(); //int[] positionInBoneGroup = new int[3]; //List<int> indiceList = new List<int>(); //List<int> allBoneIndexes = new List<int>(); //List<int> vertexUsingBone = new List<int>(); //VertexData vertexData; //for (int i = 0; i < subMeshCount; i++) //{ // int[] indices = mesh.GetIndices(i); // for (int indiceIter = 0; indiceIter < indices.Length; indiceIter += 3) // { // // indice start // for (int k = 0; k < 3; k++) // { // int indiceIndex = indiceIter + k; // int vertexIndex = indices[indiceIndex]; // positionInBoneGroup[k] = -1; // int ii = 0; // while (ii < boneGroupVertex.Count) // { // if (boneGroupVertex[ii].index == vertexIndex) // { // positionInBoneGroup[k] = ii; // break; // } // ii++; // continue; // } // if (positionInBoneGroup[k] == -1) // { // vertexData = getVertexData(mesh, vertexIndex, vertexLayout); // vertexDataQueue.Add(vertexData); // // 每个点最多关联4根骨骼,所以遍历4下 // for (ii = 0; ii < 4; ii++) // { // float bone = vertexData.boneIndex[ii]; // if (allBoneIndexes.IndexOf((int)bone) == -1 && vertexUsingBone.IndexOf((int)bone) == -1) // { // vertexUsingBone.Add((int)bone); // } // } // } // } // // 没到达最大骨骼数 目前不知道这个24最大骨骼限制是干嘛用的 // if (allBoneIndexes.Count + vertexUsingBone.Count <= MaxBoneCount) // { // for (int l = 0; l < vertexUsingBone.Count; l++) // { // allBoneIndexes.Add(vertexUsingBone[l]); // } // int num8 = 1; // for (int l = 0; l < 3; l++) // { // if (positionInBoneGroup[l] == -1) // { // indiceList.Add(vertexDatas.Count + boneGroupVertex.Count - 1 + num8++); // } // else // { // indiceList.Add(vertexDatas.Count + positionInBoneGroup[l]); // } // } // for (int l = 0; l < vertexDataQueue.Count; l++) // { // boneGroupVertex.Add(vertexDataQueue[l]); // } // } // else // { // for (int l = 0; l < boneGroupVertex.Count; l++) // { // vertexDatas.Add(boneGroupVertex[l]); // } // // 回退一位? // indiceIter -= 3; // boneGroupVertex = new List<VertexData>(); // allBoneIndexes = new List<int>(); // } // // 最后一个face了 // if (indiceIter + 3 == indices.Length) // { // for (int l = 0; l < boneGroupVertex.Count; l++) // { // vertexDatas.Add(boneGroupVertex[l]); // } // boneGroupVertex = new List<VertexData>(); // allBoneIndexes = new List<int>(); // } // vertexUsingBone = new List<int>(); // vertexDataQueue = new List<VertexData>(); // // indice end // } //} long vertexStart = 0L; long vertexLength = 0L; long indiceStart = 0L; long indiceLength = 0L; long boneEndPosition = 0L; // 记录vertexBuffer在总buffer里的起始位置,一般是0 vertexStart = fileStream.Position; // 用于算包围球,计算模型的重心(所有点的位置均值) Vector3 vertexPositionAddup = new Vector3(0, 0, 0); // 遍历mesh里的所有定点 for (int j = 0; j < mesh.vertexCount; j++) { Vector3 vector = mesh.vertices[j]; // 写入position wxFileUtil.WriteData(fileStream, vector.x * -1f, vector.y, vector.z); // 统计position,用于算包围盒 vertexPositionAddup.Set(vertexPositionAddup.x + vector.x * -1f, vertexPositionAddup.y + vector.y, vertexPositionAddup.z + vector.z); // 如果vertexLayout有normal,写入normal if (vertexLayout.NORMAL) { Vector3 vector2 = mesh.normals[j]; wxFileUtil.WriteData(fileStream, vector2.x * -1f, vector2.y, vector2.z); } // 如果vertexLayout有color,写入color if (vertexLayout.COLOR) { Color color = mesh.colors[j]; wxFileUtil.WriteData(fileStream, color.r, color.g, color.b, color.a); } // 如果vertexLayout有uv,写入uv if (vertexLayout.UV) { Vector2 vector3 = mesh.uv[j]; wxFileUtil.WriteData(fileStream, vector3.x, vector3.y * -1f + 1f); } // 如果vertexLayout有uv1,写入uv1 if (vertexLayout.UV1) { Vector2 vector4 = mesh.uv2[j]; wxFileUtil.WriteData(fileStream, vector4.x, vector4.y * -1f + 1f); } if (vertexLayout.BONE) { BoneWeight boneWeight = mesh.boneWeights[j]; wxFileUtil.WriteData( fileStream, boneWeight.weight0, boneWeight.weight1, boneWeight.weight2, boneWeight.weight3 ); wxFileUtil.WriteData( fileStream, (float)boneWeight.boneIndex0, (float)boneWeight.boneIndex1, (float)boneWeight.boneIndex2, (float)boneWeight.boneIndex3 ); } // 如果vertexLayout有tangent,写入tangent if (vertexLayout.TANGENT) { Vector4 vector5 = mesh.tangents[j]; wxFileUtil.WriteData(fileStream, vector5.x * -1f, vector5.y, vector5.z, vector5.w); } } // 记录vertexBuffer在buffer里的结束位置 vertexLength = fileStream.Position - vertexStart; // 记录indiceBuffer在buffer里的起始位置 indiceStart = fileStream.Position; // indiceBuffer指的是给模型绘制面时,每个面所用的顶点index。在unity里叫triangles int[] triangles = mesh.triangles; for (int j = 0; j < triangles.Length; j++) { wxFileUtil.WriteData(fileStream, (ushort)triangles[j]); } // 记录indexBuffer在buffer里的结束位置 indiceLength = fileStream.Position - indiceStart; // 因为读取的时候是根据4位来读的所以末尾补0 long isFour = indiceLength % 4; if (isFour != 0) { wxFileUtil.WriteData(fileStream, (ushort)0.0); } long boneStartPosition = fileStream.Position; if (mesh.bindposes != null && mesh.bindposes.Length != 0) { Matrix4x4[] bonePoses = new Matrix4x4[mesh.bindposes.Length]; for (int i = 0; i < mesh.bindposes.Length; i++) { bonePoses[i] = mesh.bindposes[i]; bonePoses[i] = bonePoses[i].inverse; Vector3 s = default(Vector3); Quaternion q = default(Quaternion); Vector3 pos = default(Vector3); MathUtil.Decompose(bonePoses[i].transpose, out s, out q, out pos); pos.x *= -1f; q.x *= -1f; q.w *= -1f; bonePoses[i] = Matrix4x4.TRS(pos, q, s); } for (int i = 0; i < mesh.bindposes.Length; i++) { Matrix4x4 matrix4x = bonePoses[i]; } for (int i = 0; i < mesh.bindposes.Length; i++) { Matrix4x4 inverse = bonePoses[i].inverse; for (int j = 0; j < 16; j++) { wxFileUtil.WriteData(fileStream, inverse[j]); } } boneEndPosition = fileStream.Position; } long bonePoseLength = boneEndPosition - boneStartPosition; fileStream.Close(); metadata.AddField("indiceFormat", 1); // BIT16 = 1,BIT32 = 2 metadata.AddField("vertexLayout", vertexLayout.GetLayoutString()); //"POSITION,NORMAL,COLOR,UV,BLENDWEIGHT,BLENDINDICES,TANGENT", metadata.AddField("vertexStart", 0); metadata.AddField("vertexLength", vertexLength); metadata.AddField("indiceStart", vertexLength); // indice的偏移量 metadata.AddField("indiceLength", indiceLength); // indice的长度 metadata.AddField("bonePoseStart", boneStartPosition); metadata.AddField("bonePoseLength", bonePoseLength); metadata.AddField("capsule", GetCapsule()); bool succ = false; JSONObject bonesObject = GetSkinPaths(renderer.sharedMesh.name, ref succ); metadata.AddField("rootBone", bonesObject.GetField("root")); metadata.AddField("bones", bonesObject.GetField("bones")); metadata.AddField("version", 1); // 加入submesh JSONObject subMeshs = new JSONObject(JSONObject.Type.ARRAY); #if !UNITY_2017_1_OR_NEWER int indexStart = 0; #endif ushort subMeshCount = (ushort)mesh.subMeshCount; for (int i = 0; i < subMeshCount; i++) { JSONObject subMeshObj = new JSONObject(JSONObject.Type.OBJECT); #if !UNITY_2017_1_OR_NEWER subMeshObj.AddField("start", indexStart); subMeshObj.AddField("length", mesh.GetIndices(i).Length); indexStart += mesh.GetIndices(i).Length; #else subMeshObj.AddField("start", mesh.GetIndexStart(i)); subMeshObj.AddField("length", mesh.GetIndexCount(i)); #endif subMeshs.Add(subMeshObj); } // submesh一般指的是mesh里的其中一部分,所以用indiceBuffer的区间表示 metadata.AddField("subMeshs", subMeshs); return(fileStream.ToArray()); }
// 导出AnimationTrack private int ExportAnimationTrack(AnimationTrack animationTrack, JSONObject trackListArr, JSONObject clipListArr) { JSONObject trackJSON = GenerateBaseTrack(animationTrack, PlaybaleTrackTypeMap["AnimationTrack"]); trackJSON.AddField("applyAvatarMask", animationTrack.applyAvatarMask); JSONObject infiniteClipOffsetPositionArr = new JSONObject(JSONObject.Type.ARRAY); JSONObject infiniteClipOffsetRotationArr = new JSONObject(JSONObject.Type.ARRAY); trackJSON.AddField("infiniteClipOffsetPosition", infiniteClipOffsetPositionArr); trackJSON.AddField("infiniteClipOffsetRotation", infiniteClipOffsetRotationArr); #if UNITY_2018_3_OR_NEWER trackJSON.AddField("trackOffset", TrackOffsetMap[animationTrack.trackOffset]); #else if (animationTrack.applyOffsets) { trackJSON.AddField("trackOffset", TrackOffsetMap["ApplyTransformOffsets"]); } else { trackJSON.AddField("trackOffset", TrackOffsetMap["Auto"]); } #endif #if UNITY_2019_1_OR_NEWER infiniteClipOffsetPositionArr.Add(-animationTrack.infiniteClipOffsetPosition.x); infiniteClipOffsetPositionArr.Add(animationTrack.infiniteClipOffsetPosition.y); infiniteClipOffsetPositionArr.Add(animationTrack.infiniteClipOffsetPosition.z); infiniteClipOffsetRotationArr.Add(-animationTrack.infiniteClipOffsetRotation.x); infiniteClipOffsetRotationArr.Add(animationTrack.infiniteClipOffsetRotation.y); infiniteClipOffsetRotationArr.Add(animationTrack.infiniteClipOffsetRotation.z); infiniteClipOffsetRotationArr.Add(-animationTrack.infiniteClipOffsetRotation.w); #else infiniteClipOffsetPositionArr.Add(-animationTrack.openClipOffsetPosition.x); infiniteClipOffsetPositionArr.Add(animationTrack.openClipOffsetPosition.y); infiniteClipOffsetPositionArr.Add(animationTrack.openClipOffsetPosition.z); infiniteClipOffsetRotationArr.Add(-animationTrack.openClipOffsetRotation.x); infiniteClipOffsetRotationArr.Add(animationTrack.openClipOffsetRotation.y); infiniteClipOffsetRotationArr.Add(animationTrack.openClipOffsetRotation.z); infiniteClipOffsetRotationArr.Add(-animationTrack.openClipOffsetRotation.w); #endif if (animationTrack.avatarMask != null) { WXAvatarMask mask = new WXAvatarMask(animationTrack.avatarMask); string uid = AddDependencies(mask); trackJSON.AddField("avatarMask", uid); } else { trackJSON.AddField("avatarMask", new JSONObject(JSONObject.Type.NULL)); } JSONObject positionArr = new JSONObject(JSONObject.Type.ARRAY); positionArr.Add(-animationTrack.position.x); positionArr.Add(animationTrack.position.y); positionArr.Add(animationTrack.position.z); trackJSON.AddField("position", positionArr); JSONObject rotationArr = new JSONObject(JSONObject.Type.ARRAY); rotationArr.Add(-animationTrack.rotation.x); rotationArr.Add(animationTrack.rotation.y); rotationArr.Add(animationTrack.rotation.z); rotationArr.Add(-animationTrack.rotation.w); trackJSON.AddField("rotation", rotationArr); JSONObject matchTargetFieldsJSON = new JSONObject(JSONObject.Type.OBJECT); trackJSON.AddField("matchTargetFields", matchTargetFieldsJSON); matchTargetFieldsJSON.AddField("PositionX", (animationTrack.matchTargetFields & MatchTargetFields.PositionX) == MatchTargetFields.PositionX); matchTargetFieldsJSON.AddField("PositionY", (animationTrack.matchTargetFields & MatchTargetFields.PositionY) == MatchTargetFields.PositionY); matchTargetFieldsJSON.AddField("PositionZ", (animationTrack.matchTargetFields & MatchTargetFields.PositionZ) == MatchTargetFields.PositionZ); matchTargetFieldsJSON.AddField("RotationX", (animationTrack.matchTargetFields & MatchTargetFields.RotationX) == MatchTargetFields.RotationX); matchTargetFieldsJSON.AddField("RotationY", (animationTrack.matchTargetFields & MatchTargetFields.RotationY) == MatchTargetFields.RotationY); matchTargetFieldsJSON.AddField("RotationZ", (animationTrack.matchTargetFields & MatchTargetFields.RotationZ) == MatchTargetFields.RotationZ); UnityEditor.SerializedObject serializedObject = new UnityEditor.SerializedObject(animationTrack); UnityEditor.SerializedProperty serializedClip = serializedObject.FindProperty("m_Clips"); JSONObject clipsIndexArr = trackJSON.GetField("clips"); if (animationTrack.inClipMode) // 普通clip // 貌似有时候序列化的m_Clips顺序跟 timelineClipList 的顺序对不上,但是很难复现。没有找到顺序可以必定对上的方法,先这样吧 { IEnumerable <TimelineClip> timelineClipList = animationTrack.GetClips(); int num = 0; foreach (TimelineClip timelineClip in timelineClipList) { JSONObject clipJSON = GenerateBaseTimelineClip(timelineClip, PlaybaleClipTypeMap["Animation"]); JSONObject clipData = new JSONObject(JSONObject.Type.OBJECT); float m_PostExtrapolationTime = (float)serializedClip.FindPropertyRelative("Array.data[" + num + "].m_PostExtrapolationTime").doubleValue; float m_PreExtrapolationTime = (float)serializedClip.FindPropertyRelative("Array.data[" + num + "].m_PreExtrapolationTime").doubleValue; clipJSON.SetField("postExtrapolationTime", m_PostExtrapolationTime); clipJSON.SetField("preExtrapolationTime", m_PreExtrapolationTime); clipJSON.AddField("data", clipData); bool m_Recordable = serializedClip.FindPropertyRelative("Array.data[" + num + "].m_Recordable").boolValue; clipData.AddField("recordable", m_Recordable); string clipPath = ExportAnimationClip(timelineClip.animationClip); if (string.IsNullOrEmpty(clipPath)) { clipData.AddField("clip", JSONObject.nullJO); } else { clipData.AddField("clip", clipPath); } AnimationPlayableAsset asset = (AnimationPlayableAsset)timelineClip.asset; // clipData.AddField("clipCaps", ClipCapsMap.ContainsKey(timelineClip.clipCaps) ? ClipCapsMap[timelineClip.clipCaps] : ClipCapsMap[ClipCaps.None]); // clipData.AddField("duration", (float)asset.duration); #if UNITY_2018_3_OR_NEWER // 2018_3才开始支持 clipData.AddField("applyFootIK", asset.applyFootIK); #else clipData.AddField("applyFootIK", false); #endif #if UNITY_2019_1_OR_NEWER // 2019_1才开始支持 clipData.AddField("loop", LoopModeMap[asset.loop]); #else clipData.AddField("loop", LoopModeMap["UseSourceAsset"]); #endif clipData.AddField("useTrackMatchFields", asset.useTrackMatchFields); JSONObject clipMatchTargetFieldsJSON = new JSONObject(JSONObject.Type.OBJECT); clipData.AddField("matchTargetFields", clipMatchTargetFieldsJSON); clipMatchTargetFieldsJSON.AddField("PositionX", (asset.matchTargetFields & MatchTargetFields.PositionX) == MatchTargetFields.PositionX); clipMatchTargetFieldsJSON.AddField("PositionY", (asset.matchTargetFields & MatchTargetFields.PositionY) == MatchTargetFields.PositionY); clipMatchTargetFieldsJSON.AddField("PositionZ", (asset.matchTargetFields & MatchTargetFields.PositionZ) == MatchTargetFields.PositionZ); clipMatchTargetFieldsJSON.AddField("RotationX", (asset.matchTargetFields & MatchTargetFields.RotationX) == MatchTargetFields.RotationX); clipMatchTargetFieldsJSON.AddField("RotationY", (asset.matchTargetFields & MatchTargetFields.RotationY) == MatchTargetFields.RotationY); clipMatchTargetFieldsJSON.AddField("RotationZ", (asset.matchTargetFields & MatchTargetFields.RotationZ) == MatchTargetFields.RotationZ); JSONObject clipPositionArr = new JSONObject(JSONObject.Type.ARRAY); clipPositionArr.Add(-asset.position.x); clipPositionArr.Add(asset.position.y); clipPositionArr.Add(asset.position.z); clipData.AddField("position", clipPositionArr); JSONObject clipRotationArr = new JSONObject(JSONObject.Type.ARRAY); clipRotationArr.Add(-asset.rotation.x); clipRotationArr.Add(asset.rotation.y); clipRotationArr.Add(asset.rotation.z); clipRotationArr.Add(-asset.rotation.w); clipData.AddField("rotation", clipRotationArr); clipsIndexArr.Add(ExportTimelineClip(clipJSON, clipListArr)); num++; } } else // infiniteClip { #if UNITY_2019_1_OR_NEWER // 2019_1才开始支持 AnimationClip infiniteClip = animationTrack.infiniteClip; #else // 序列化取出私有变量 UnityEditor.SerializedObject trackSerializedObject = new UnityEditor.SerializedObject(animationTrack); UnityEditor.SerializedProperty animClipSerialize = trackSerializedObject.FindProperty("m_AnimClip"); AnimationClip infiniteClip = animClipSerialize.objectReferenceValue as AnimationClip; #endif string infinityClipPath = ExportAnimationClip(infiniteClip); if (string.IsNullOrEmpty(infinityClipPath)) { trackJSON.SetField("infinityClip", JSONObject.nullJO); } else { trackJSON.SetField("infinityClip", infinityClipPath); } } // 导出子track JSONObject childrenJSON = trackJSON.GetField("children"); IEnumerable <TrackAsset> childTrackAssetList = animationTrack.GetChildTracks(); List <int> indexList = ExportTrackList(childTrackAssetList, trackListArr, clipListArr); foreach (int index in indexList) { childrenJSON.Add(index); } return(ExportTrack(trackJSON, trackListArr)); }
protected override JSONObject ToJSON(WXHierarchyContext context) { JSONObject json = new JSONObject(JSONObject.Type.OBJECT); JSONObject data = new JSONObject(JSONObject.Type.OBJECT); json.AddField("type", getTypeName()); json.AddField("data", data); data.AddField("active", true); // ngui prefab don't need binding script if (this.behaviour != null /* && !WXBridge.isNGUIPreset */) { var script = MonoScript.FromMonoBehaviour(this.behaviour); string path = new WXEngineScript(script).Export(context.preset); context.AddResource(path); data.AddField("__uuid", path); } if (this.behaviour != null) { Type myObjectType = behaviour.GetType(); FieldInfo[] fields = myObjectType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo field in fields) { if (!field.IsDefined(typeof(SerializeField)) && !field.IsPublic) { continue; } WXMonoBehaviourPropertiesHandler.HandleProperty(field, behaviour, data, context); } } // clear {} json.GetField("data", (JSONObject _data) => { var shouldBeRemoved = new List <string>(); foreach (var _key in _data.keys) { // Debug.Log(_type); // Debug.Log(_data[_type] + " == " + _data[_type].GetType().ToString()); var _value = _data[_key].ToString(); // Debug.Log("key:"+_key+" value:"+_value); if (_data[_key].IsNull || _value == "{}") { shouldBeRemoved.Add(_key); // _data.RemoveField(_key); // Debug.Log("remove: " + _key); } } foreach (var k in shouldBeRemoved) { _data.RemoveField(k); } }); return(json); }