public void RestoreHierarchy(AssetDocumentHierarchyElementContainer hierarchyElementContainer, IPsiSourceFile sourceFile) { if (myIsRestored) { return; } lock (myLockObject) { if (myIsRestored) { return; } myIsRestored = true; AssetDocumentHierarchyElementContainer = hierarchyElementContainer; IsScene = sourceFile.GetLocation().ExtensionWithDot.Equals(UnityYamlConstants.Scene); var offset = 0; // concating arrays to one by index. see GetElementByInternalIndex too PrepareElements(myOtherBoxedElements, offset); offset += myOtherBoxedElements.Count; PrepareElements(myTransformElements, offset); offset += myTransformElements.Count; PrepareElements(myGameObjectHierarchies, offset); offset += myGameObjectHierarchies.Count; PrepareElements(myComponentElements, offset); offset += myComponentElements.Count; PrepareElements(myScriptComponentElements, offset); offset += myScriptComponentElements.Count; foreach (var prefabInstanceHierarchy in GetPrefabInstanceHierarchies()) { var correspondingSourceObjects = new HashSet <ExternalReference>(); foreach (var modification in prefabInstanceHierarchy.PrefabModifications) { var target = modification.Target; if (!(target is ExternalReference externalReference)) { continue; } correspondingSourceObjects.Add(externalReference); } foreach (var correspondingSourceObject in correspondingSourceObjects) { var fakeAnchor = PrefabsUtil.GetImportedDocumentAnchor(prefabInstanceHierarchy.Location.LocalDocumentAnchor, correspondingSourceObject.LocalDocumentAnchor); myOtherFakeStrippedElements.Add(new StrippedHierarchyElement( new LocalReference(sourceFile.PsiStorage.PersistentIndex, fakeAnchor), prefabInstanceHierarchy.Location, correspondingSourceObject)); } } } }
public IHierarchyElement GetHierarchyElement(string ownerGuid, ulong anchor, PrefabImportCache prefabImportCache) { if (myLocalAnchorToHierarchyElement.TryGetValue(anchor, out var result)) { if (!result.IsStripped || prefabImportCache == null) // stipped means, that element is not real and we should import prefab { return(result); } } if (result != null && IsScene && result.IsStripped) { var prefabInstance = result.PrefabInstance; var correspondingObject = result.CorrespondingSourceObject; if (prefabInstance != null && correspondingObject != null) { anchor = PrefabsUtil.Import(prefabInstance.LocalDocumentAnchor, correspondingObject.LocalDocumentAnchor); } } if (prefabImportCache != null) { var elements = prefabImportCache.GetImportedElementsFor(ownerGuid, this); if (elements.TryGetValue(anchor, out var importedResult)) { return(importedResult); } } return(null); }
public IHierarchyElement GetHierarchyElement(Guid?ownerGuid, ulong anchor, PrefabImportCache prefabImportCache) { var result = SearchForAnchor(anchor); if (result != null) { if (!(result is IStrippedHierarchyElement) || prefabImportCache == null) // stipped means, that element is not real and we should import prefab { return(result); } } // In prefabs files, anchor for stripped element is always generated by formula in PrefabsUtil. This means // that after we import elements from prefab file into another file, we could reuse anchor from stripped element to // get real element (in current implementation, imported objects are store in PrefabImportCache) // It is not true(!!!) for scene files, anchors for scene files could be generated by sequence generator. This means, // that anchor for stripped element could be '19' for example, but imported element will have another anchor. // // To unify all logic, if ownerGuid is related to scene file and achor points to stripped file, we will // use new anchor which calculated in same way with prefab import if (result != null && IsScene && result is IStrippedHierarchyElement strippedHierarchyElement) { var prefabInstance = strippedHierarchyElement.PrefabInstance; var correspondingObject = strippedHierarchyElement.CorrespondingSourceObject; anchor = PrefabsUtil.GetImportedDocumentAnchor(prefabInstance.LocalDocumentAnchor, correspondingObject.LocalDocumentAnchor); } if (prefabImportCache != null && ownerGuid != null) { var elements = prefabImportCache.GetImportedElementsFor(ownerGuid.Value, this); if (elements.TryGetValue(anchor, out var importedResult)) { return(importedResult); } } return(null); }
private ImportedInspectorValues ProcessPrefabModifications(IPsiSourceFile currentSourceFile, AssetDocument assetDocument) { var result = new ImportedInspectorValues(); if (assetDocument.HierarchyElement is IPrefabInstanceHierarchy prefabInstanceHierarchy) { foreach (var modification in prefabInstanceHierarchy.PrefabModifications) { if (!(modification.Target is ExternalReference externalReference)) { continue; } if (modification.PropertyPath.Contains(".")) { continue; } var location = new LocalReference(currentSourceFile.PsiStorage.PersistentIndex.NotNull("owningPsiPersistentIndex != null"), PrefabsUtil.GetImportedDocumentAnchor(prefabInstanceHierarchy.Location.LocalDocumentAnchor, externalReference.LocalDocumentAnchor)); result.Modifications[new ImportedValueReference(location, modification.PropertyPath)] = (modification.Value, new AssetReferenceValue(modification.ObjectReference)); } } return(result); }
private ImportedUnityEventData ProcessPrefabModifications(IPsiSourceFile currentFile, AssetDocument document) { var result = new ImportedUnityEventData(); if (document.HierarchyElement is IPrefabInstanceHierarchy prefabInstanceHierarchy) { var assetMethodDataToModifiedFields = new OneToSetMap <(LocalReference, string, int), string>(); foreach (var modification in prefabInstanceHierarchy.PrefabModifications) { if (!(modification.Target is ExternalReference externalReference)) { continue; } if (!modification.PropertyPath.Contains("m_PersistentCalls")) { continue; } var location = new LocalReference(currentFile.PsiStorage.PersistentIndex, PrefabsUtil.GetImportedDocumentAnchor(prefabInstanceHierarchy.Location.LocalDocumentAnchor, externalReference.LocalDocumentAnchor)); var parts = modification.PropertyPath.Split('.'); var unityEventName = parts[0]; var dataPart = parts.FirstOrDefault(t => t.StartsWith("data")); if (dataPart == null) { continue; } if (!int.TryParse(dataPart.RemoveStart("data[").RemoveEnd("]"), out var index)) { continue; } result.UnityEventToModifiedIndex.Add((location, unityEventName), index); var last = parts.Last(); if (last.Equals("m_MethodName") && modification.Value is AssetSimpleValue assetSimpleValue) { result.AssetMethodNameInModifications.Add(assetSimpleValue.SimpleValue); } assetMethodDataToModifiedFields.Add((location, unityEventName, index), last); } foreach (var(_, set) in assetMethodDataToModifiedFields) { if (!set.Contains("m_MethodName")) { result.HasEventModificationWithoutMethodName = true; } } } return(result); }