Okay, I did some digging.
If you have a MonoBehaviour in a .cs file in Unity, and put that MonoBehaviour on a GameObject in a scene or a prefab, it will look like this in the .unity or .asset file:
--- !u!114 &2117605206
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 2117605203}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 741d034f3dbc23b489b1a6207bfdcd03, type: 3}
m_Name:
m_EditorClassIdentifier:
The guid there is the guid of the .cs file. The fileID is always 11500000 in this instance (more on that later). And you can find it in the .meta file of that .cs file. In my example, it looks like this:
fileFormatVersion: 2
guid: 741d034f3dbc23b489b1a6207bfdcd03
timeCreated: 1499434280
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
So the guid there matches, and Unity uses that to find the correct file.
For a MonoBehaviour from a .dll, matters are different. It looks like this:
--- !u!114 &2117605207
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 2117605203}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1865668834, guid: 5e824220ee2a9dc47963e93f71515cf7, type: 3}
m_Name:
m_EditorClassIdentifier:
Note that the fileID has a different value. In this case, the guid is the guid of the .dll, while the fileID is an internal reference in the .dll. That internal reference is stored in the Library folder. In one of the folders inside the library, there will be a file containing information about MonoBehaviours inside the dll. It’ll be named dllgui.info (so in the example above, “5e824220ee2a9dc47963e93f71515cf7.info”. For my case, it’s in the folder “5e”, I have no idea if that’s consistent in any way.
That file contains a “representations” field, looking like this:
- serializedVersion: 3
name: TempTempTestBehaviour
thumbnail:
m_Format: 5
m_Width: 64
m_Height: 64
m_RowBytes: 256
image data: 16384
_typelessdata: 00ffffff00ffffff00ffffff00fff //SNIP, there's 32.000 more characters here
guid: 5e824220ee2a9dc47963e93f71515cf7
path:
localIdentifier: 1259625427
thumbnailClassID: 115
flags: 0
scriptClassName: TempTempTestBehaviour
- serializedVersion: 3
name: TempTempTestBehaviour2
thumbnail:
m_Format: 5
m_Width: 64
m_Height: 64
m_RowBytes: 256
image data: 16384
_typelessdata: 00ffffff00ffffff00ffff //SNIP, there's 32.000 more characters here
guid: 5e824220ee2a9dc47963e93f71515cf7
path:
localIdentifier: 1865668834
thumbnailClassID: 115
flags: 0
scriptClassName: TempTempTestBehaviour2
As you can tell, I named my scripts “TempTempTestBehaviour”, and the localIdentifier matches for TempTempTestBehaviour2 and the entry from my example scene where I put the script.
I did some further testing, and it’s apparent that the localIdentifier in the .info file changes when you change the name and/or namespace of the file in the dll. This means that unlike MonoBehaviours in .cs files that are identified by their file’s guid, you cannot change either of those things in a .dll-MonoBehaviour without causing the script reference to become missing.
Now, this isn’t any good news. I guess you could manage a cache of id-to-script name data to help you recover, but that’s kinda a crap shoot. Sorry I couldn’t be any more help, but it’s at least interesting information.