Hi all, I'm having some troubles with adding objects to assets, I've made a scriptable object and now I want to add materials and textures to it. Problem is that it seems a scripted asset doesn't seem to be able to be a parent asset, so I'll go: Code (csharp): AssetDatabase.AddObjectToAsset(myTexture, myAsset); AssetDatabase.ImportAsset(AssetImporter.GetAssetPath(myTexture)); And what I end up with is: Assets/ myAsset.asset (empty)/ myAsset (texture) myAsset (scripted asset) Can anyone recomment a course of action for me? And I REALLY don't want to convert my scriptable asset into a prefab ( I know that will make things work out better ) Thanks for any input!
I'm assuming you're talking about a class that inherits from ScriptableObject, if not, can you clarify what you mean by a scriptable asset? From the documentation: "A class you can derive from if you want to create objects that don't need to be attached to game objects. This is most useful for assets which are only meant to store data." These kind of objects are not designed to be attached to anything, so they will not work with parenting. Consider using MonoBehaviour instead.
It's derived from a ScriptableObject, it is a pure data storage class so I don't want it to be a MonoBehaviour, though it is possible to use one, but I really want to avoid that. All of that is kinda beside the point though I need to be able to add textures/materials/whatever to a ScriptableObject derived asset in my project without it bugging out on me. I get: MyAsset (some sort of empty asset/object/thing) MyAsset (my texture) MyAsset (my actual scriptable object) I need: MyAsset (my actual scriptable object) MyAsset (my texture)
I don't understand why you're opposed to using MonoBehaviour, it will solve your problem, and has very very little difference in terms of performance.
I have my reasons which aren't really relevant here, since that's not my question. If someone can tell me for sure that it is impossible to add a texture to a ScriptableObject asset then I may consider the monobehaviour option.
Ok, I'm probably not understanding something here, so I'll drop the Monobehaviour argument for the time being. Can you clarrify what you mean by attaching a texture to a ScriptableObject? You can have a Texture2D as an exposed member variable on a ScriptableObject You can have a ScriptableObject on a GameObject through some fairly hackish workarounds, but you cannot ever have a texture by itself in the hierarchy. Your explanation confuses me because it seems to say that the texture is an entity by itself in the hierarchy view. If you're talking about making the ScriptableObject item in the Project view a parent in a similar way to a prefab or folder, then that is impossible (even for MonoBehaviour, or anything other than folders or prefabs for that matter), and getting as far as you did surprises me.
Are there any particular reasons as to why you want to include your textures and materials into ".asset" file? This kind of breaks the whole beauty of working with assets in Unity. Asset files are generally created by scripts for dynamically generated content. From the reference documentation: http://unity3d.com/support/documentation/ScriptReference/AssetDatabase.AddObjectToAsset.html That is good because you should not be using "AddObjectToAsset" with prefabs Apparently there are a number of bad side effects to this.
I am running into a similar problem. I have content being generated by an editor script, and I would like to save this content on a ScriptableObject. Adding Texture, Material, Mesh, or ScriptableObject assets as a sub asset of a ScriptableObject results in an empty asset being created, with the original parent ScriptableObject as a child. As the OP stated, this is not expected behaviour! Is there any way around this?
I have reported the issue of the blank parent asset to Unity and they have accepted that it is a bug. Basically the main asset becomes "UnityEngine.GenericAsset" instead of the asset that was specified (which becomes a child). There is no workaround to this at the moment (or at least none that were suggested or that I can find). If you add a material then that will usually become the parent asset. If anybody does know of a workaround then it would be greatly appreciated here too!
Code (csharp): myTexture.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(myTexture, myAsset); AssetDatabase.Refresh(); This will add the object without messing up the asset in the Project View. Just tested to confirm, this works with Textures, as well as any other Object.
Doesn't work for me. Have you tried this with myAsset being a ScriptableObject? What I am after is being able to create a ScriptableObject and then adding a few sub objects to it. Right now, when adding the sub object, it makes both the object being added and myAsset child of a new asset. Edit: If I remove the hide flag on the object being added, using AssetDatabase.SaveAssets(); crashes Unity.
Yeah, I just tested it by creating a ScriptableObject called TextureContainer. I put a List<Texture2D> in it, and made a simple EditorWindow that allows you to add textures to the selected TextureContainer asset. It works perfectly. This is also the technique I use in my GUI Editor; I create a GUIAsset (ScriptableObject) asset, then when controls are added to it, I set their hide flags to HideInHierarchy, and the problem is solved. EDIT: Just saw your last edit. I've never encountered that problem before. Also, I'm using Unity 3.5.5f3. If you are using a newer version, things may have changed. I didn't do an extensive test, but when I did test my GUI Editor in 4.0 it appeared to work fine. Hmmm...
I must be missing something... I create a ScriptableObject via menu and it appears in my project. Then in an editor script, I get a reference to the object being selected. Code (csharp): Object selection = Selection.activeObject; Later in this editor Script Code (csharp): // Create some Test Object AnimationClip clip = new AnimationClip(); clip.name = "Special Font"; AssetDatabase.AddObjectToAsset(clip, selection); //AssetDatabase.SaveAssets(); // This crashes. If I save the project and then navigate back to this object, we get the results in the image below where it moved the Main Asset and made it a child along with the object to be added to a new generic object with the same name as the main asset. I am using 4.0.
If I do the same operations but the Target object is a Material instead of a ScriptableObject, it works.
I've developed a workaround for this issue: As you can see, I have a main scriptable that contains sub-scriptables, that when selected shows up in the inspector. While I did not manage to get rid of the "asset container" thingy (AFAICS it's not part of the serialized data, so most likely a dummy created by the editor: no way around it...), what I did was redirect the inspector from the container to the main asset. The idea is to mark the main scriptable with a [MainAsset] attribute, have a custom editor that picks it up, create the relevant editor, and redirect calls to it. It works even if the main asset has a custom editor. By default the main asset shows up as a child of the container as you guys noticed, but you can optionally hide it. I've attached a package with sample code, try it for yourself! Create an asset (it has 3 sub-assets by default): From the context menu, you can add more sub-assets, or hide the main asset: What I haven't figured out is a way to reorder items in the project view (ie in the asset file itself), which would be nicer. As you can see in the first screenshot the sub-assets are not sorted the same in the project view and in my own list.
No no, it's there. You must be using Unity 5? UT changed how "no particular type" assets (such as the scriptable object container I mention above) are handled: before they were just untyped Objects, now they have exposed a new DefaultAsset type (and apparently more assets types are coming for 5.x, yay . So the fix is simple, just change DefaultAssetEditor with this: [CustomEditor(typeof(DefaultAsset))] (instead of [CustomEditor(typeof(Object))]) I've also attached the updated package.
Hey, actually no. I am using 4.6 - but for some reason that thing didn't show up. I've even searched the source files for some MenuItem thing.
Well there are MenuItems ! See TestMainAsset.cs: const string kContext = "CONTEXT/TestMainAsset/"; [MenuItem(kContext + "Add Sub-Asset")] Did you maybe rename the file but not this string? No compile errors?
This work around seems promising. Thank you for sharing it. I'm running Unity 5.3.1p2, and when the root "Main Asset" object is selected in the Project panel, the Inspector is empty. It does not mirror the Inspector when the ScriptableObject "Main Asset" is selected. After adding Debug.Log() calls in each of the methods in DefaultAssetEditor.cs, it became clear that the methods were not being called. It seems as though the CustomEditor attribute is failing or the root object isn't a DefaultAsset or a UnityEngine.Object. I realize this thread is a year old, but if you have any suggestions, I'd certain appreciate hearing them. Thanks!
I'm not on 5.3 yet so I don't know, but I saw this in the 5.3.3p1 release notes: (770926) - Scripting: Fixed issues with Scriptable objects added as sub assets with AssetDatabase.AddObjectToAsset. Any chance this could be related?
Strangely, I just experienced similar issue in unity 2017.1 However, mine was occurring when the second argument of AddObjectToAsset was a string - a path relative to Assets folder. Once I've pluged-in the main asset as an object (instead of the path), the AssetDatabase.SaveAssets() didn't complain