Created
April 28, 2022 08:11
-
-
Save kraj0t/41997eeaa5c7c12cc953056a93f28bd6 to your computer and use it in GitHub Desktop.
[Unity] Retrieve a component's fileId and its gameObject's asset guid (if any)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary>Universal method for retrieving the fileId of a component inside a saved gameObject, and the guid to the file that contains the gameObject. | |
/// The gameObject could live in a prefab or in a scene, and the component does not need to be at the root gameObject of the prefab.</summary> | |
/// <param name="comp"></param> | |
/// <returns>A tuple containing the guid and the fileId of the component. Returns null if the component's gameObject has not been saved to a scene or a prefab.</returns> | |
public static Tuple<string, long> GetComponentIdentifiers(Component comp) | |
{ | |
// Check if the component is the direct instance from the prefab. | |
// In the Editor, this means that the prefab asset is selected and the component is showing in the Inspector. | |
if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(comp, out string guid, out long fileId)) | |
{ | |
return new Tuple<string, long>(guid, fileId); | |
} | |
// Check if the component comes from a prefab that has been added to a scene. | |
var origComp = PrefabUtility.GetCorrespondingObjectFromSource(comp); | |
if (origComp != null && AssetDatabase.TryGetGUIDAndLocalFileIdentifier(origComp, out guid, out fileId)) | |
{ | |
return new Tuple<string, long>(guid, fileId); | |
} | |
// Last resort: check if the component comes from a prefab that is being edited in the prefab mode. | |
var prefabStage = PrefabStageUtility.GetPrefabStage(comp.gameObject); | |
if (prefabStage != null) | |
{ | |
guid = AssetDatabase.AssetPathToGUID(prefabStage.prefabAssetPath); | |
if (!guid.IsNullOrEmpty()) | |
{ | |
fileId = GetLocalIdentifierInFile(comp); | |
return new Tuple<string, long>(guid, fileId); | |
} | |
} | |
Log.Error($"Have you saved the prefab? Is it a prefab? Component {comp.GetType().Name} in gameObject {comp.gameObject.name} has no GUID or fileID assigned!"); | |
return null; | |
} | |
/// <summary>Also called fileID.</summary> | |
/// <param name="o"></param> | |
/// <returns>0 if not part of an asset. Otherwise, the fileID.</returns> | |
public static long GetLocalIdentifierInFile(UnityEngine.Object o) | |
{ | |
// This code was downloaded from https://gist.github.com/peposso/4aa72435771d29ed20971916bdb6c12a | |
// That link contains other potentially useful methods that we might need in the future. | |
var inspectorModeInfo = typeof(SerializedObject).GetProperty("inspectorMode", BindingFlags.NonPublic | BindingFlags.Instance); | |
if (inspectorModeInfo != null) | |
{ | |
var so = new SerializedObject(o); | |
inspectorModeInfo.SetValue(so, InspectorMode.Debug, null); | |
var prop = so.FindProperty("m_LocalIdentfierInFile"); | |
return prop.longValue; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment