示例#1
0
        private static void Write(UnsafeWriter writer, ModificationHierarchyElement value)
        {
            value.Id.WriteTo(writer);
            value.CorrespondingSourceObject.WriteTo(writer);
            value.PrefabInstance.WriteTo(writer);
            writer.Write(value.IsStripped);
            value.TransformParentId.WriteTo(writer);
            WriteDictionary(writer, value.myRootIndexes, (w, v) =>
            {
                if (w.WriteNullness(v))
                {
                    w.Write(v.Value);
                }
            });

            WriteDictionary(writer, value.myNames, (w, v) => w.Write(v));
        }
        public void ConsumeGameObject(GameObjectHierarchyElement gameObject, TransformHierarchyElement transformHierarchyElement, ModificationHierarchyElement modifications)
        {
            string name = null;

            if (modifications != null)
            {
                name = modifications.GetName(new FileID(null, gameObject.Id.fileID));
            }
            if (name == null)
            {
                name = gameObject.Name;
            }

            if (name?.Equals(string.Empty) == true)
            {
                name = null;
            }

            myParts.Push(name ?? "...");

            int?rootOrder = null;

            if (modifications != null)
            {
                rootOrder = modifications.GetRootIndex(transformHierarchyElement.Id.WithGuid(null));
            }

            if (rootOrder == null)
            {
                rootOrder = transformHierarchyElement.RootOrder;
            }

            myIndex.Push(rootOrder ?? 0);
        }
示例#3
0
 protected bool Equals(ModificationHierarchyElement other)
 {
     return(Id.Equals(other.Id));
 }
示例#4
0
        // Invariant : startGameObject is Transform Component if it is not stripped
        // This method traverse scene hierarchy via visiting transform components and push corresponding to transform GameObject into consumer
        private void ProcessSceneHierarchyFromComponentToRootInner(IPsiSourceFile currentFile, IUnityHierarchyElement startUnityObject,
                                                                   IUnityCachedSceneProcessorConsumer consumer, ModificationHierarchyElement modifications)
        {
            var currentUnityObject = startUnityObject;

            while (currentUnityObject != null)
            {
                // Unity object could be stripped, it means, that corresponding real object belongs to another yaml file
                // Also, it has reference to prefab instance in current file, which stores all prefab modification
                if (currentUnityObject.IsStripped)
                {
                    var correspondingId  = currentUnityObject.CorrespondingSourceObject;
                    var prefabInstanceId = currentUnityObject.PrefabInstance;



                    if (correspondingId == null || prefabInstanceId == null)
                    {
                        return;
                    }

                    var prefabInstance        = mySceneElements.GetValues(new SceneElementId(currentFile, prefabInstanceId)).FirstOrDefault() as ModificationHierarchyElement;
                    var prefabSourceFilePaths = myGuidCache.GetAssetFilePathsFromGuid(correspondingId.guid);
                    if (prefabSourceFilePaths.Count > 1 || prefabSourceFilePaths.Count == 0)
                    {
                        return;
                    }

                    var unityModule = currentFile.PsiModule as UnityExternalFilesPsiModule;
                    if (unityModule == null)
                    {
                        return;
                    }

                    if (!unityModule.NotNull("externalFilesModuleFactory.PsiModule != null")
                        .TryGetFileByPath(prefabSourceFilePaths.First(), out var prefabSourceFile))
                    {
                        return;
                    }


                    var prefabStartGameObject = mySceneElements.GetValues(new SceneElementId(prefabSourceFile, correspondingId.WithGuid(null))).FirstOrDefault();

                    if (prefabStartGameObject == null)
                    {
                        return; // TODO [vkrasnotsvetov] 19.3 Handle case, when prefab contains prefab which contains prefab
                    }
                    if (!prefabStartGameObject.IsStripped)
                    {
                        // !u!4 is transform. If tag is different, let's extract transform, there are two cases:
                        // 1) prefabStartGameObject is GameObject(!u!1), take its transform
                        // 2) prefabStartGameObject is Component, so get attached gameobject and from this gameobject take transform component
                        if (!(prefabStartGameObject is TransformHierarchyElement))
                        {
                            var attachedGameObject = prefabStartGameObject;
                            if (attachedGameObject is ComponentHierarchyElement componentHierarchyElement)
                            {
                                var sceneId = new SceneElementId(prefabSourceFile, componentHierarchyElement.GameObject);
                                attachedGameObject = mySceneElements.GetValues(sceneId).FirstOrDefault();
                            }

                            if (attachedGameObject is GameObjectHierarchyElement gameObjectHierarchyElement)
                            {
                                var sceneId = new SceneElementId(prefabSourceFile, gameObjectHierarchyElement.TransformId);
                                prefabStartGameObject = mySceneElements.GetValues(sceneId).FirstOrDefault();
                            }
                            else
                            {
                                prefabStartGameObject = null;
                            }
                        }
                    }
                    ProcessSceneHierarchyFromComponentToRootInner(prefabSourceFile, prefabStartGameObject, consumer, prefabInstance);
                    currentUnityObject = prefabInstance != null
                        ? mySceneElements.GetValues(new SceneElementId(currentFile, prefabInstance.TransformParentId)).FirstOrDefault()
                        : null;
                }
                else
                {
                    // assert that startGameObject is GameObject
                    var transformComponent = currentUnityObject as TransformHierarchyElement;
                    if (transformComponent == null)
                    {
                        return; // strange, log here
                    }
                    Assertion.Assert(currentUnityObject is TransformHierarchyElement, "currentUnityObject is TransformHierarchyElement");



                    var fatherTransformId = new SceneElementId(currentFile, transformComponent.Father);
                    var father            = mySceneElements.GetValues(fatherTransformId).FirstOrDefault();

                    var goId = new SceneElementId(currentFile, transformComponent.GameObject);

                    var gameObject = mySceneElements.GetValues(goId).FirstOrDefault() as GameObjectHierarchyElement;
                    if (gameObject == null)
                    {
                        return; // strange, log here
                    }
                    consumer.ConsumeGameObject(gameObject, transformComponent, modifications);
                    currentUnityObject = father;
                }
            }
        }
示例#5
0
        public void AddPrefabModification(IBuffer buffer)
        {
            var anchor = UnitySceneDataUtil.GetAnchorFromBuffer(buffer);

            if (anchor == null)
            {
                return;
            }

            var lexer = new YamlLexer(buffer, false, false);

            lexer.Start();

            TokenNodeType currentToken;

            var transformParentId = FileID.Null;

            while ((currentToken = lexer.TokenType) != null)
            {
                if (currentToken == YamlTokenType.INDENT)
                {
                    var indentSize = lexer.TokenEnd - lexer.TokenStart;
                    lexer.Advance();
                    currentToken = lexer.TokenType;

                    if (currentToken == YamlTokenType.NS_PLAIN_ONE_LINE_IN)
                    {
                        var text = buffer.GetText(new TextRange(lexer.TokenStart, lexer.TokenEnd));
                        if (text.Equals(UnityYamlConstants.TransformParentProperty))
                        {
                            lexer.Advance();
                            UnitySceneDataUtil.SkipWhitespace(lexer);
                            currentToken = lexer.TokenType;

                            if (currentToken == YamlTokenType.COLON)
                            {
                                lexer.Advance();

                                var result = UnitySceneDataUtil.GetFileId(buffer, lexer);
                                if (result != null)
                                {
                                    transformParentId = result;
                                }
                            }
                        }
                        else if (text.Equals(UnityYamlConstants.ModificationsProperty))
                        {
                            var names       = new Dictionary <FileID, string>();
                            var rootIndexes = new Dictionary <FileID, int?>();
                            GetModifications(buffer, lexer, indentSize, names, rootIndexes);
                            var id = new FileID(null, anchor);
                            Elements[id] = new ModificationHierarchyElement(id, null, null, false, transformParentId, rootIndexes, names);
                            return;
                        }
                    }
                }
                else
                {
                    lexer.Advance();
                }
            }
        }