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
        }
Exemplo n.º 2
0
        /**
         * 登记一个要转换的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);
            }
        }