I am experiencing a rather annoying issue with all my scripable object data assets.
After closing the editor and coming back to it later, Unity no longer sees my data as valid.
How it should be vs what happens after loading the editor again.
Forcing my script to recompile immediatly resolves the issue temporarily. Hitting play also caused the issue to resolve.
Here is my code:
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
[CreateAssetMenu(fileName = "Data", menuName = "ScriptableObjects/StagePaletteData", order = 1)]
public class StagePaletteData : ScriptableObject
{
[Range(0, 63)] public byte[] Addresses = new byte[3];
#if UNITY_EDITOR
[SerializeField] private Color[] colors = new Color[3];
#endif
#if UNITY_EDITOR
public Texture2D colorPalette = null;
private Color32[] colorPaletteData;
void OnValidate() {
GetColorPaletteData();
SetColors(colors, Addresses);
}
void GetColorPaletteData() {
var data = colorPalette.GetRawTextureData<Color32>();
colorPaletteData = data.ToArray();
}
void SetColors(Color[] colors, byte[] addresses) {
for (int i = 0; i < colors.Length; i++) {
colors[i] = colorPaletteData[addresses[i]];
}
}
#endif
}
Is there something I am missing here? Or perhaps this is a bug?
Make sure your script name matches the class name. That class should be in a file called StagePaletteData.cs
.
It matches.
Assets\ScriptableObjects\StagePaletteData.cs
In the inspector, choosing debug mode allows me to choose a script. I am able to drop in the StagePaletteData.cs and now it seems me problem is solved.
Quite annoying as I’d have to insert this everytime I create a new asset, but at least it is something.
In your left screenshot when it is “working”, the greyed-out script field should have a reference to your script in it, but it is displaying None
. This means that it’s not finding your script properly for some reason. The most usual cause of this kind of issue is if your filename doesn’t match the class name, but as you’ve ruled that out, there must be something else causing the reference to break.
Makes sense, but quite odd. I do have the name right and it fixes itself after a recompile, so I’d imagine that something else is causing it to not automatically fill in that reference.
Even when working, it still is missing that reference.
The linkage between a scriptable object instance and its script is twofold. For one it is the GUID contained in the .meta file for the script, but the other requirement is the class and file naming requirement as you list above.
For instance, this is my StartingShips scriptable object: (StartingShips.asset, NOT the meta file)
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 541a8be390a8a4758b654d7d6604eb8e, type: 3}
m_Name: StartingShips
m_EditorClassIdentifier:
InitialValue: 3
Save: 0
The guid you see above references the .meta file of the ScriptableObject script, in this case Datasack.cs
When I go look in Datasack.cs.meta
, I see this:
fileFormatVersion: 2
guid: 541a8be390a8a4758b654d7d6604eb8e
timeCreated: 1517584268
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
… and the GUID matches. You can look in these with any text editor.
Try cloning your SO script to a fresh renamed file, see if you can make instances that retain their connection.
1 Like
Mine is the same.
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bc4f08e4a12d9ff4cbff80cea21699a0, type: 3}
m_Name: SpinningSpitter_0
m_EditorClassIdentifier: Assembly-CSharp::StagePaletteData
Addresses: 131c26
colors:
- {r: 0.53333336, g: 0.07058824, b: 1, a: 1}
- {r: 0, g: 0.54509807, b: 0.58431375, a: 1}
- {r: 1, g: 0.5254902, b: 0.2784314, a: 1}
colorPalette: {fileID: 2800000, guid: 3ffc7985cd4abe641aac17a15bc5c5c1, type: 3}
fileFormatVersion: 2
guid: bc4f08e4a12d9ff4cbff80cea21699a0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
This however is after that fix of using debug mode to choose the script. Ever since I did that I can not replicate the original issue as they all generate correctly.
If you rename the class from within visual studio, the currently infuriating state of that function (for actually the past decade, going back to Monobehavior) is that it renames the .cs file but does NOT rename the .cs.meta file.
Therefore, Unity throws out your original GUID, which you MAY have already used, and creates a new one when it creates the new .meta file. It is the single most Fisher-Price non-professional feature there is in Unity. It is probably responsible for more bugs and lost engineering time than anything else.
You can trivially reproduce it if you don’t believe me. Here’s how:
- make a Scriptable Object class called Foo.cs
- make an instance of a Foo
- go into Visual Studio
- rename class Foo to Bar and check the box that says rename source file
- go back to Unity
Tada, your ScriptableObject instance now has a missing script. Same thing goes if it was used in a prefab, or anywhere in any scene.
Is that perhaps what happened? It’s a miserable error because to me the MINIMUM thing Unity should do is not only tell you one time “I deleted the unused .meta file,” but it should RIGHT THEN create a list of affected assets. It has all of that in a database FFS, and flag them PERMANENTLY in red, or at least offer to let you en-masse fix them.
“Hey, we noticed that script Foo.cs disappeared and it was used by 2753 different prefabs. If you have a new script to replace it, tell us and we’ll replace it right now.”
1 Like
I did rename my script at one point, but I had gone and recreated all my test assets for it after that anyway.
Perhaps it got confused at some point along the way, but by me using debug mode I forced it to update?
I don’t use anything complex for coding. I just stick with Notepad++ so I can learn to not rely on those advanced features, even if it slows me down.
1 Like