private void getFileIdAndPrefabInfo(GameObject gameObject, string _resourcePath) { if (gameObject != null) { fileIdInOriginalSource = WXUtility.GetFileIdInInspector(gameObject); } #if UNITY_2018_4_OR_NEWER string guid; long fileId; if (gameObject != null) { isPrefabNode = PrefabUtility.IsPartOfPrefabInstance(gameObject) || PrefabUtility.IsPartOfPrefabAsset(gameObject); bool isDisconnectedPrefabInstance = PrefabUtility.IsDisconnectedFromPrefabAsset(gameObject); // Debug.LogError("gameObject.name: " + gameObject.name + " isDisconnectedPrefabInstance: " + isDisconnectedPrefabInstance + " IsPartOfAnyPrefab: " + isPrefabNode + " isAssetPrefabNode: " + PrefabUtility.IsPartOfPrefabAsset(gameObject) + " isPrefabInstanceNode: " + PrefabUtility.IsPartOfPrefabInstance(gameObject) + " IsPartOfModelPrefab: " + PrefabUtility.IsPartOfModelPrefab(gameObject) + " IsPartOfNonAssetPrefabInstance: " + PrefabUtility.IsPartOfNonAssetPrefabInstance(gameObject) + " IsPartOfPrefabThatCanBeAppliedTo: " + PrefabUtility.IsPartOfPrefabThatCanBeAppliedTo(gameObject) + " IsPartOfRegularPrefab: " + PrefabUtility.IsPartOfRegularPrefab(gameObject) + " IsPartOfVariantPrefab: " + PrefabUtility.IsPartOfVariantPrefab(gameObject) + " IsPrefabAssetMissing: " + PrefabUtility.IsPrefabAssetMissing(gameObject)); if (isPrefabNode && !isDisconnectedPrefabInstance) { GameObject sourceObj = PrefabUtility.GetCorrespondingObjectFromOriginalSource(gameObject); if (sourceObj != null && AssetDatabase.TryGetGUIDAndLocalFileIdentifier(sourceObj, out guid, out fileId)) { string path = AssetDatabase.GUIDToAssetPath(guid); unityAssetPath = path; if (!path.EndsWith(".prefab")) { path = path + ".prefab"; } prefabPath = path; fileIdInOriginalSource = fileId; if (_resourcePath != prefabPath) { isPrefabNodeInParentInstance = PrefabUtility.IsPartOfPrefabInstance(gameObject); GameObject sourceGameObject = gameObject; try { // 处理S1->P1->P2的场景下,导出P1,P2应该是P1的outermostPrefabRoot if (!_resourcePath.EndsWith(".scene")) { GameObject source = PrefabUtility.GetCorrespondingObjectFromSourceAtPath(sourceGameObject, _resourcePath); if (source) { sourceGameObject = source; } } } catch { } isOutermostPrefabRoot = PrefabUtility.IsOutermostPrefabInstanceRoot(sourceGameObject); prefabRootInstanceFileId = WXUtility.GetFileIdInInspector(sourceGameObject.transform); bool isAnyPrefabInstanceRoot = PrefabUtility.IsAnyPrefabInstanceRoot(gameObject); // Debug.Log("prefabObj: " + gameObject.name + " isAnyPrefabInstanceRoot: " + isAnyPrefabInstanceRoot + " isOutermostPrefabRoot: " + isOutermostPrefabRoot); if (isAnyPrefabInstanceRoot && !isOutermostPrefabRoot) // 如果不是最外层的prefabRoot // 处理S1->P1->P2的场景下,计算P2的prefabInstanceLocalId时,先找到P2的父节点,再通过父节点找到所在的P1文件,再拿到P2在P1中的Instance,再通过其transform的fileId作为prefabInstanceLocalId { string prefabAssetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(gameObject.transform.parent.gameObject); // GameObject instanceRoot = PrefabUtility.GetCorrespondingObjectFromSource(gameObject); GameObject instanceRoot = PrefabUtility.GetCorrespondingObjectFromSourceAtPath(gameObject, prefabAssetPath); isNestedPrefabRoot = true; if (instanceRoot != null) { prefabRootInstanceFileId = WXUtility.GetFileIdInInspector(instanceRoot.transform); } } // string prefabAssetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(gameObject); // bool isModelPrefabInstance = prefabAssetPath.EndsWith(".FBX"); // // 对于model的根节点,统一设置其prefabRootInstanceFileId // if (isModelPrefabInstance && isAnyPrefabInstanceRoot) { // GameObject instanceRoot = PrefabUtility.GetCorrespondingObjectFromOriginalSource(gameObject); // prefabRootInstanceFileId = WXUtility.GetFileIdInInspector(instanceRoot.transform); // } } // Debug.Log("sourceObj: " + sourceObj.name + " guid: " + guid + " fileID: " + fileIdInOriginalSource + " path: " + prefabPath); } else { Debug.LogError("2 can't get component localId " + gameObject.name); } } } #else if (gameObject != null && PrefabUtility.GetPrefabParent(gameObject) != null) { try { PrefabType type = PrefabUtility.GetPrefabType(gameObject); if (type == PrefabType.DisconnectedPrefabInstance || type == PrefabType.DisconnectedModelPrefabInstance || type == PrefabType.MissingPrefabInstance) { return; } UnityEngine.Object prefabGameObject = PrefabUtility.GetPrefabParent(gameObject); string path = AssetDatabase.GetAssetPath(prefabGameObject); unityAssetPath = path; if (!path.EndsWith(".prefab")) { path = path + ".prefab"; } prefabPath = path; if (prefabPath == _resourcePath) { isPrefabNodeInParentInstance = false; } else { GameObject prefabRoot = PrefabUtility.FindRootGameObjectWithSameParentPrefab(gameObject); if (prefabRoot == gameObject) { isOutermostPrefabRoot = true; prefabRootInstanceFileId = WXUtility.GetFileIdInInspector(gameObject.transform); } isPrefabNodeInParentInstance = true; } fileIdInOriginalSource = WXUtility.GetFileIdInInspector(prefabGameObject); } catch { // 应该不会走道这里单独导出prefab时,nativeComponent已经是一个实例了,会被GetCorrespondingObjectFromOriginalSource方法抛错 Debug.LogError("2 can't get component localId " + gameObject.name); } } #endif }
/** * 登记一个要转换的component,返回component的id * * @param component * @param entity 挂component的entity * @param nativeComponent 对应的u3dcomponent,排重用 */ public int AddComponent(WXComponent component, Component nativeComponent = null) { string cacheKey = nativeComponent != null? nativeComponent.GetInstanceID().ToString() + component.GetType() : ""; // -----------------------获取component的objectId start------------------------------------- if (nativeComponent != null) { component.objectId = WXUtility.GetFileIdInInspector(nativeComponent); } #if UNITY_2018_4_OR_NEWER if (nativeComponent != null) { try { Component prefabComp = PrefabUtility.GetCorrespondingObjectFromOriginalSource(nativeComponent); string guid; long fileId; if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(prefabComp, out guid, out fileId)) { string path = AssetDatabase.GUIDToAssetPath(guid); if (!path.EndsWith(".prefab")) { path = path + ".prefab"; } component.filePath = path; component.objectId = fileId; } // Debug.Log("UNITY_2018_1_OR_NEWER component objectID" + fileId); } catch { // 如果导出一个prefab,这个在场景中给这个prefab加了一个entity,那么这个entity中的component其实不在unity prefab文件中, // 而是在scene的diffData中,因此调用PrefabUtility.GetCorrespondingObjectFromOriginalSource这个方法时会抛异常, // 就直接用inspector中的m_LocalIdentfierInFile即可。 // Debug.LogWarning("UNITY_2018_1_OR_NEWER prefab component objectID " + component.objectId); } } #else if (nativeComponent != null) { try { UnityEngine.Object prefabComp = PrefabUtility.GetPrefabParent(nativeComponent); PropertyInfo inspectorModeInfo = typeof(UnityEditor.SerializedObject).GetProperty("inspectorMode", BindingFlags.NonPublic | BindingFlags.Instance); string path = AssetDatabase.GetAssetPath(prefabComp); if (!path.EndsWith(".prefab")) { path = path + ".prefab"; } component.filePath = path; SerializedObject serializedObject = new SerializedObject(prefabComp); inspectorModeInfo.SetValue(serializedObject, UnityEditor.InspectorMode.Debug, null); SerializedProperty localIdProp = serializedObject.FindProperty("m_LocalIdentfierInFile"); if (localIdProp != null) { long localId = localIdProp.longValue; component.objectId = localId; // Debug.LogWarning("component localId " + localIdProp.longValue); } else { component.objectId = 0; // Debug.LogWarning("can't get component localId"); } } catch { // 应该不会走道这里。单独导出prefab时,nativeComponent已经是一个实例了,会被GetCorrespondingObjectFromOriginalSource方法抛错 // Debug.LogWarning("component use default localId " + component.objectId); } } #endif if ((component.objectId == 0 || component.objectId == -1) && nativeComponent != null) { Debug.LogError("component fileId is 0, component type" + component.getTypeName() + " entity name: " + nativeComponent.gameObject.name); } // -----------------------获取component的objectId end------------------------------------- // 以原生component作为key建立一个缓存表,如果已存在,则复用 // // 后续更新:这里不仅仅是复用 // 因为AddComponent的时候,有可能是外面对这个component做了一些新的修改 // 所以还要调用一次OnIterateTo,走一下相关更新逻辑 if ( nativeComponent != null && componentDictionary.ContainsKey(cacheKey) // && component.GetType() == componentDictionary[nativeComponent].GetType() ) { //Debug.Log("" + nativeComponent.GetInstanceID()); var bbcomp = componentDictionary[cacheKey]; bbcomp.OnIterateTo(this); return(bbcomp.arrayId); } else { componentList.Add(component); int num = componentList.Count() - 1; component.arrayId = num; if (nativeComponent != null) { //Debug.Log("" + nativeComponent.GetInstanceID()); componentDictionary.Add(cacheKey, component); } component.OnIterateTo(this); return(num); } }