I’m making a migration tool for scene’s and am now including prefabs and nested prefabs. To migrate the data I need to know what type of class/MonoBehaviour the document is (can be found with the original fileID and guid). For a normal prefab (without the nesting) this can be done by going in the scene file to the PrefabInstance -> M_Modification -> M_Modifications -> Target -> fileID This fileID then is the flag of the document in the prefab file i’m working with (a quick ctrl + f shows what script it is).
But this does not seem to work when prefabs are nested. It then has a fileID that does not exist anywhere else in the project (that i can find). It seems just randomly generated like the normal prefab and a reference to something i can’t find as it changes when the script is re-added.
I’ve exported it to a package and unzipped it but there isn’t any special mapping other then the normal files. But the import in a new project works fine, which should mean that the fileID is some kind of a reference as the reference stays intact. (I’ve added the package to the post)
Any information about the nested prefab fileID would be appreciated.
Is there any way to calculate the FileID_of_nested_PrefabInstance with the .prefab and .prefab.meta files? Currently i would have to calculate the fileID for every prefab and every yamldocument in that prefab which seems like a workaround.
Lets say you have Prefab B, that nests prefab A. In that case, the file called B.prefab will contain a PrefabInstance object. This object will have a FileID which is randomly generated when prefab B is created and it can’t be calculated.
Unfortunately I don’t think that the AssetDatabase will work as I just have the files and not the loaded in Unity project.
For context, I’m making a migration tool to move scenes and now prefabs from one project to another. But that also means that i don’t have access to the AssetDatabase in the original project as this code is executed from the new project.
Now to clarify the problem:
I have a scene file called Example.unity in this scene there is a prefab(Prefab.prefab) and in this prefab there is a prefab nested (PrefabNested.prefab). Now I look through the scene and find the PrefabInstance.m_SourcePrefab.guid element and move to that prefab (Prefab.prefab) to also migrate that prefab.
Now in this prefab (Prefab.prefab) I find another PrefabInstance but this time without the guid so i had no idea which prefab this references. For the tool I’m writing I need to change the PrefabInstance.m_Modification.m_Modifications[ ].propertyPath as this field should be migrated. But to know what i need to change it to I need to know which script it actually is which I’m working on. For this I need to look in the nested prefab(PrefabNested.prefab). But the fileID in the Prefab.prefab doesn’t match the fileID in the nested prefab (NestedPrefab.prefab). So first I need find which prefab it is, the script is on.
With the current solution i would have to loop through all prefabs in the project and find all scripts in those prefabs and run the following on it :
This would then result in all the fileIDs being calculated and I would then be able to find the script and prefab that I’m looking for.
This is definitely a solution that could work and I think this is currently the way to go, but it would be amazing if I could in some way calculate a fileID that would point me to the correct prefab from within the Prefab.prefab. This would make the processing a lot easier.
But if these fileIDs are generated and I won’t be able to read them then I’ll just have to parse all prefabs.
For future reference (because this took me some tinkering to figure out) if a scene has a modification for double nested prefab the fileId in the scene file ‘modification’ is calculated by adding each layer of prefab instance to the xor ‘^’ operation.
- PrefabA
-- PrefabB
--- PrefabC```
the fileId for the modification listed in the scene file would be
```(<PrefabA fileId in scene file> ^ <PrefabB fileId in PrefabA file> ^ <PrefabC fileId in PrefabB file>) & 0x7fffffffffffffff```
I was thinking… isn’t it posible to have fileid conflicts if you have several nested prefabs? Imagine this hierarchy
- Prefab A
- Prefab B
- child 0
- child 1
- ...
- Prefab C
- child 0
- child 1
- ...
I know there is a small chance but there is still a small posibility that any children of B and C end up having the same fileid when being referenced from prefab A since you can edit any of those prefabs separately (you can open PrefabB and start generating GameObjects)
Actually I was able to create this conflict manually (by changing the ids on the prefabs from a text editor) and I ended up with a corrupted prefab
Duplicate identifier -1764472761. File: "Assets/TestPrefab.prefab".
UnityEditor.EditorApplication:Internal_CallUpdateFunctions ()
Error loading the file 'Assets/TestPrefab.prefab'. File has multiple objects with same identifiers. Probably caused by a merge.
UnityEditor.EditorApplication:Internal_CallUpdateFunctions ()
I think it’s posible that this happens… or am I missing something here?