Changing namespace of MonoBehaviour in DLL causes missing script issue

While the warning is reported in Console, the missing component is strangely disappeared from Inspector, leaving no direct way to fix it. The only way I found is to create a new GameObject and copy every other valid component to it, which takes considerable amount of time.

Does anyone have a better solution?

This problem also occurred when I first transferred my scripts in asset folder to a dll file. Obviously it was quite frustrating to recreate all the prefabs that contained these scripts.:frowning:

Have seen several people run into this issue. I’ve heard that this thing helps a bit. It’s essentially a tool that looks at the serialized fields and tries to figure out which script is used.

1 Like

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.

4 Likes

Thanks a lot for your information! Yeah, I kinda anticipate that it could be hard to identify the original class after renaming it.

But at least, Unity should display the panel for the missing component as it normally does after a script attached to a GameObject is deleted, thus allowing developers to choose their proper class. Ideally, the properties should be preserved.

Looking forward to future improvement.

That’s probably a more specific bug. Unity sometimes deletes things that is missing. I’ve mostly seen that on StateMachineBehaviours, but not surprised that it has happened on MonoBehaviours. If you can make it happen consistently, you should for sure send a bug report.

1 Like