static UnityAssetParser() { // add a dummy object for "null" string emptyId = new UnityObjectKey(Guid.Empty, 0).ToString(); ObjectDatabase.AddObject(emptyId, new NullObject(emptyId)); }
/// <summary> /// /// </summary> /// <param name="yamlNode"></param> /// <param name="fileGuid">The guid of the file containing this element.</param> /// <param name="fileId"></param> /// <param name="guid"></param> protected UnityObjectKey ParseReference(YamlMappingNode yamlNode, UnityObjectKey parentKey) { long fileId = 0; Guid guid = Guid.Empty; YamlNode fileIdNode; if (yamlNode.Children.TryGetValue("fileID", out fileIdNode)) { YamlScalarNode fileIdScalarNode = (YamlScalarNode)fileIdNode; string fileIdStr = fileIdScalarNode.Value; fileId = long.Parse(fileIdStr); if (fileId != 0) { // guid defaults to this file guid = parentKey.AssetGuid; } } YamlNode guidNode; if (yamlNode.Children.TryGetValue("guid", out guidNode)) { YamlScalarNode guidScalarNode = (YamlScalarNode)guidNode; string guidStr = guidScalarNode.Value; guid = new Guid(guidStr); } return(new UnityObjectKey(guid, fileId)); }
/// <summary> /// Parses the specified file. /// </summary> public override void ParseFile(string absolutePath) { Guid guid = Guid.Empty; if (Path.GetExtension(absolutePath) != ".meta") { // find the meta file string metaFilePath = absolutePath + ".meta"; if (File.Exists(metaFilePath)) { guid = UnityMetaParser.ReadGuidFromMeta(metaFilePath); } } // create a project object for the document string uniqueId = guid != Guid.Empty ? guid.ToString() : absolutePath; ObjectDatabase.AddObject(uniqueId, new UnityAsset(absolutePath, uniqueId)); using (StreamReader fileReader = new StreamReader(new FileStream(absolutePath, FileMode.Open, FileAccess.Read))) { YamlStream stream = new YamlStream(); stream.Load(new UnityTextReader(fileReader)); // each document is one UnityEngine.Object foreach (YamlDocument document in stream.Documents) { YamlMappingNode documentNode = (YamlMappingNode)document.RootNode; if (documentNode.Anchor == null) { // might be a JSON file (XRSettings.asset), skip for now continue; } long fileId = long.Parse(documentNode.Anchor); UnityObjectKey key = new UnityObjectKey(guid, fileId); KeyValuePair <YamlNode, YamlNode> rootNode = documentNode.Children.First(); YamlScalarNode rootNodeScalar = (YamlScalarNode)rootNode.Key; if (rootNodeScalar.Value == "GameObject") { ObjectDatabase.AddObject(key, new UnityGameObject(uniqueId, document, key)); } else if (rootNodeScalar.Value == "Prefab") { ObjectDatabase.AddObject(key, new UnityPrefabInstance(uniqueId, document, key)); } else { ObjectDatabase.AddObject(key, new UnityComponent(uniqueId, document, key)); } } } }
protected virtual void Parse(YamlDocument yaml, UnityObjectKey key) { YamlMappingNode rootNode = (YamlMappingNode)yaml.RootNode; // create prefab link YamlNode prefabNode; if (rootNode.Children.TryGetValue("m_PrefabParentObject", out prefabNode)) { YamlMappingNode prefabMappingNode = (YamlMappingNode)prefabNode; UnityObjectKey reference = ParseReference(prefabMappingNode, key); AddRelationship(reference, "is-instance-of-prefab", "has-instance"); } }
/// <summary> /// Reads a <see cref="UnityPrefabInstance"/> from the specified Yaml node. /// </summary> public UnityPrefabInstance(string documentId, YamlDocument yaml, UnityObjectKey key) : base(documentId, key) { YamlMappingNode rootNode = (YamlMappingNode)yaml.RootNode; YamlMappingNode objectNode = (YamlMappingNode)rootNode.Children.First().Value; // read parent prefab YamlNode prefabNode; if (objectNode.Children.TryGetValue("m_ParentPrefab", out prefabNode)) { YamlMappingNode prefabMappingNode = (YamlMappingNode)prefabNode; UnityObjectKey reference = ParseReference(prefabMappingNode, key); AddRelationship(reference, "is-instance-of-prefab", "has-prefab-instance"); } // read instance modifications YamlMappingNode modificationNode = (YamlMappingNode)objectNode.Children["m_Modification"]; YamlSequenceNode modifications = ((YamlSequenceNode)modificationNode.Children["m_Modifications"]); foreach (YamlMappingNode listNode in modifications.Children) { UnityObjectKey reference; YamlScalarNode propertyPathNode = (YamlScalarNode)listNode.Children["propertyPath"]; YamlScalarNode valueNode = (YamlScalarNode)listNode.Children["value"]; // save overridden GameObject name if (propertyPathNode.Value == "m_Name") { Name = valueNode.Value; } YamlMappingNode targetNode = (YamlMappingNode)listNode.Children["target"]; reference = ParseReference(targetNode, key); AddRelationship(reference, "modifies-member", "modified-by-instance"); YamlMappingNode objectReferenceNode = (YamlMappingNode)listNode.Children["objectReference"]; reference = ParseReference(objectReferenceNode, key); if (!reference.IsEmpty) { AddRelationship(reference, "has-reference-to", "is-referenced-by"); } } }
/// <summary> /// Reads a <see cref="UnityGameObject"/> from the specified Yaml node. /// </summary> public UnityGameObject(string documentId, YamlDocument yaml, UnityObjectKey key) : base(documentId, yaml, key) { YamlMappingNode rootNode = (YamlMappingNode)yaml.RootNode; YamlMappingNode objectNode = (YamlMappingNode)rootNode.Children.First().Value; // read object name Name = ((YamlScalarNode)objectNode.Children["m_Name"]).Value; // read object component links YamlSequenceNode components = ((YamlSequenceNode)objectNode.Children["m_Component"]); foreach (YamlMappingNode listNode in components.Children) { YamlMappingNode component = listNode.Children["component"] as YamlMappingNode; UnityObjectKey reference = ParseReference(component, key); AddRelationship(reference, "has-component", ""); } }
/// <summary> /// Reads a <see cref="UnityGameObject"/> from the specified Yaml node. /// </summary> public UnityObject(string documentId, YamlDocument yaml, UnityObjectKey key) : base(key) { // add to document DocumentId = documentId.ToString(); AddRelationship(DocumentId, "is-in-document", "document-contains-object"); if (yaml != null) { try { Parse(yaml, key); } catch (Exception e) { ParseError = e; } } }
/// <summary> /// Reads a <see cref="UnityGameObject"/> from the specified Yaml node. /// </summary> public UnityObject(string documentId, YamlDocument yaml, UnityObjectKey key) : base(key) { // add to document DocumentId = documentId.ToString(); AddRelationship(DocumentId, "is-in-document", "document-contains-object"); if (yaml != null) { YamlMappingNode rootNode = (YamlMappingNode)yaml.RootNode; // create prefab link YamlNode prefabNode; if (rootNode.Children.TryGetValue("m_PrefabParentObject", out prefabNode)) { YamlMappingNode prefabMappingNode = (YamlMappingNode)prefabNode; UnityObjectKey reference = ParseReference(prefabMappingNode, key); AddRelationship(reference, "is-instance-of-prefab", "has-instance"); } } }
/// <summary> /// Reads a <see cref="UnityComponent"/> from the specified Yaml node. /// </summary> public UnityComponent(string documentId, YamlDocument yaml, UnityObjectKey key) : base(documentId, yaml, key) { YamlMappingNode rootNode = (YamlMappingNode)yaml.RootNode; KeyValuePair <YamlNode, YamlNode> firstNode = rootNode.Children.First(); YamlMappingNode objectNode = (YamlMappingNode)firstNode.Value; TypeName = ((YamlScalarNode)firstNode.Key).Value; foreach (KeyValuePair <YamlNode, YamlNode> kv in objectNode.Children) { YamlMappingNode valueMapping = kv.Value as YamlMappingNode; switch (((YamlScalarNode)kv.Key).Value) { case "m_GameObject": { m_gameObjectKey = ParseReference(valueMapping, key); AddRelationship(m_gameObjectKey, "is-component-of", ""); break; } case "m_Script": { m_scriptKey = ParseReference(valueMapping, key); AddRelationship(m_scriptKey, "is-instance-of-script", "is-used-on-component"); break; } case "m_Father": { UnityObjectKey reference = ParseReference(valueMapping, key); AddRelationship(reference, "has-transform-parent", ""); break; } case "m_Children": { YamlSequenceNode childrenSequenceNode = (YamlSequenceNode)kv.Value; foreach (YamlNode child in childrenSequenceNode.Children) { YamlMappingNode childMappingNode = (YamlMappingNode)child; UnityObjectKey reference = ParseReference(childMappingNode, key); AddRelationship(reference, "is-transform-child-of", ""); } break; } default: // search the entire tree for references foreach (YamlNode node in kv.Value.AllNodes) { YamlMappingNode mappingNode = node as YamlMappingNode; if (mappingNode != null) { UnityObjectKey reference = ParseReference(mappingNode, key); if (!reference.IsEmpty) { AddRelationship(reference, "has-reference-to", "is-referenced-by"); } } } break; } } }
/// <summary> /// Parses the specified file. /// </summary> public override void ParseFile(string absolutePath) { using (StreamReader fileReader = new StreamReader(new FileStream(absolutePath, FileMode.Open, FileAccess.Read))) { YamlStream stream = new YamlStream(); stream.Load(fileReader); YamlDocument document = stream.Documents[0]; YamlMappingNode rootNode = (YamlMappingNode)document.RootNode; YamlScalarNode guidNode = (YamlScalarNode)rootNode.Children["guid"]; Guid assetGuid = new Guid(guidNode.Value); string assetUniqueId = assetGuid.ToString(); // determine the asset's default file id int defaultFileId = 0; foreach (string key in rootNode.Children.Keys) { if (key.EndsWith("Importer", StringComparison.OrdinalIgnoreCase)) { int classId; if (UnityClassIds.TryGetClassIdByImporterName(key, out classId)) { defaultFileId = classId * 100000; break; } } } UnityObjectKey defaultAssetKey = new UnityObjectKey(assetGuid, defaultFileId); bool isFolderAsset = false; YamlNode folderAssetNode; if (rootNode.Children.TryGetValue("folderAsset", out folderAssetNode)) { YamlScalarNode folderAssetScalarNode = (YamlScalarNode)folderAssetNode; isFolderAsset = folderAssetScalarNode.Value == "yes"; } if (isFolderAsset) { string folderPath = Path.Combine(Path.GetDirectoryName(absolutePath), Path.GetFileNameWithoutExtension(absolutePath)); ObjectDatabase.MapFolderObject(folderPath, assetUniqueId); ObjectDatabase.AddObject(assetUniqueId, new UnityFolder(absolutePath, assetGuid)); } else { // metas shouldn't override assets we've already parsed ObjectDatabase.AddPlaceholderObject(assetUniqueId, new UnityAsset(absolutePath, assetUniqueId)); if (defaultAssetKey.FileId != 0) { ObjectDatabase.AddObject(defaultAssetKey.ToString(), new UnityDefaultAsset(assetUniqueId, defaultAssetKey)); } } // check for sprites YamlNode textureImporterNode; if (rootNode.Children.TryGetValue("TextureImporter", out textureImporterNode)) { YamlMappingNode textureImporterMappingNode = (YamlMappingNode)textureImporterNode; YamlNode fileIDToRecycleNameNode; if (textureImporterMappingNode.Children.TryGetValue("fileIDToRecycleName", out fileIDToRecycleNameNode)) { YamlMappingNode fileIDToRecycleNameMappingNode = (YamlMappingNode)fileIDToRecycleNameNode; foreach (var kv in fileIDToRecycleNameMappingNode.Children) { string fileIdStr = ((YamlScalarNode)kv.Key).Value; string name = ((YamlScalarNode)kv.Value).Value; long fileId = long.Parse(fileIdStr); UnityObjectKey spriteKey = new UnityObjectKey(assetGuid, fileId); ObjectDatabase.AddObject(spriteKey.ToString(), new UnitySprite(assetUniqueId, name, spriteKey)); } } YamlNode spriteModeNode; if (textureImporterMappingNode.Children.TryGetValue("spriteMode", out spriteModeNode)) { YamlScalarNode spriteModeScalarNode = (YamlScalarNode)spriteModeNode; if (spriteModeScalarNode.Value == "1") { // single sprite string name = Path.GetFileNameWithoutExtension(absolutePath); UnityObjectKey spriteKey = new UnityObjectKey(assetGuid, 21300000); ObjectDatabase.AddObject(spriteKey.ToString(), new UnitySprite(assetUniqueId, name, spriteKey)); } } } } }
/// <summary> /// /// </summary> public UnitySprite(string documentId, string name, UnityObjectKey key) : base(documentId, null, key) { Name = name; }
/// <summary> /// Reads a <see cref="UnityGameObject"/> from the specified Yaml node. /// </summary> public UnityGameObject(string documentId, YamlDocument yaml, UnityObjectKey key) : base(documentId, yaml, key) { }