Search Unity

Custom ScriptableObject Icons / Thumbnail

Discussion in 'Scripting' started by Fenrisul, Jul 10, 2014.

  1. Fenrisul

    Fenrisul

    Joined:
    Jan 2, 2010
    Posts:
    618
    http://docs.unity3d.com/ScriptReference/AssetPreview.html

    It seems this would be the thing to override to generate a custom thumbnail... is there any way to do this?

    Changing the icon for a script derived from ScriptableObject is easy through the project view, but that icon doesn't carry through to any instances of said ScriptableObject in the project view...


    Halp. Thanks.
     
    Blunnyn likes this.
  2. Chman

    Chman

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    721
    I'm not sure if it's possible, but if it is I'd like to know this as well !
     
  3. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Assuming;

    Code (csharp):
    1. public class AudioItem : ScriptableObject { }
    Create a folder called "Gizmos"

    In it, add a texture - 128x128 works well - named "AudioItem Icon.png".
    Yes, it's a normal space between "AudioItem" - name of your class - and "Icon".
     
  4. Chman

    Chman

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    721
  5. DarkArts-Studios

    DarkArts-Studios

    Joined:
    May 2, 2013
    Posts:
    389
    Strictly speaking this is slightly off topic, but of a similar nature.

    Another similar trick can be used with EditorWindows to give them Icons in their title bars.
    1. Create a folder in the root of your project named "Editor Default Resources"
    2. Create a folder within that new folder named "Icons"
    3. Add an image called <WindowTitle>.png (eg: MyWindow.png) (named after window title)
    Now your window will have an Icon displayed in the top left of it's titlebar.
     
    GodlikeAurora, djfunkey and Chman like this.
  6. rakkarage

    rakkarage

    Joined:
    Feb 3, 2014
    Posts:
    683
    Steedalion and GorgeGeorge like this.
  7. Fenrisul

    Fenrisul

    Joined:
    Jan 2, 2010
    Posts:
    618
  8. rakkarage

    rakkarage

    Joined:
    Feb 3, 2014
    Posts:
    683
    sorry
     
    den3d and djfunkey like this.
  9. eppz

    eppz

    Joined:
    Aug 2, 2014
    Posts:
    172
    Simply select the script asset in the project window, and you can find an Icon texture property when using Inspector in Debug mode.

    Even better: Select the script asset, then at the top left of the inspector, click on the icon, then hit "Other...".
     
    Last edited: Mar 11, 2016
  10. turbanov

    turbanov

    Joined:
    Dec 22, 2014
    Posts:
    59
    That's not for scriptableobject instances, just for scripts themselves.
     
  11. zero_equals_zero

    zero_equals_zero

    Joined:
    Jun 7, 2014
    Posts:
    89
    Awesome. wasn't aware of this. However it doesn't work when you create a subfolder in the Gizmo folder. Not sure if thats needed, but i assume when you import other assets and if they use a Gizmo folder, the system might break.
     
  12. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    1,089
    If you are referring to including the Gizmos Folder Asset in a unitypackage, then this depends on your Unity version. With newer versions of Unity you simply get a warning in the asset importer. With some versions of Unity (e.g. 5.1, 5.2) you get a bunch of ugly warnings/errors in the console. I've posted more about this in relation to the official AssetStoreTools here.

    If you are referring to the fact that someone might have a class named Tile in their project with a custom icon and another asset package may also have a Tile class, albeit in a different namespace, then yes: one icon would overwrite the other and all Tile assets would share an icon. This entire "system" is very likely extremely legacy and probably hasn't been looked at in quite a while.
     
    thegamerszone000 and djfunkey like this.
  13. zero_equals_zero

    zero_equals_zero

    Joined:
    Jun 7, 2014
    Posts:
    89
    Thanks! That will be a good read and new learning source. I appreciate your input!
     
    SonicBloomEric likes this.
  14. AntFitch

    AntFitch

    Joined:
    Jan 31, 2012
    Posts:
    243
    Anyone know how to make our icons not look pixelated? Mine look great in the Gizmos folder, but crappy when attached to the actual files in another folder in the Project View.
     
  15. ninjapretzel

    ninjapretzel

    Joined:
    Jul 19, 2011
    Posts:
    27
    Just a note to the solution that @LightStriker provided: The gizmos folder must be "Assets/Gizmos".

    It would be very useful if this wasn't required, and the Gizmos folder could be placed anywhere inside the project... It would make it easier to provide custom icons for ScriptableObjects in asset packages, and this would make it easier to provide more professional looking assets.
     
  16. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    1,089
    Assuming that your icon images are large enough to contain good detail, even when font size is maximized on a retina display (we use 256x256), you should ensure the following settings in the icon files' Import Settings:
    • Texture Type: GUI (Editor \ Legacy)
    • Filter Mode: Point
    I agree that this would be better and easier to support. I should also mention that it doesn't stop you from including this in your Asset packages (whether distributed directly or through the Asset Store using the Asset Store Tools). It is less than ideal, but it does work.
     
  17. raphick

    raphick

    Joined:
    Nov 15, 2016
    Posts:
    365
    Actually, tested in 2017.2, assigning a custom icon on the scriptableObject script asset in the inspector will automatically assign the same icon on the asset created from this scriptable object...

    ScriptableObjectsCustomIcons.jpg
     
  18. Fydar

    Fydar

    Joined:
    Feb 23, 2014
    Posts:
    69
    I have produced an asset that does exactly this!

    I always wanted to do it in my projects so I set aside some time and finally produced the asset :)

    It allows for Dynamic ScriptableObject icons with a single attribute! If you love ScriptableObjects, then you will love this asset :)

    https://www.assetstore.unity3d.com/en/#!/content/100547

    All of the above solutions, per script icons and using Gizmos only allows for one icon for every ScriptableObject, but my asset sources the icon from the ScriptableObject's data.
     

    Attached Files:

    rakkarage likes this.
  19. raphick

    raphick

    Joined:
    Nov 15, 2016
    Posts:
    365
  20. Fydar

    Fydar

    Joined:
    Feb 23, 2014
    Posts:
    69
    @raphick My asset allows for sprites to be used and rendered directly into the project window, without the need for creating Texture2Ds and caching them in the backend for each sprite. It also is completely independent of editors and is optimized for a lot of assets.

    I do find that using the RenderStaticPreview is capable of doing some of the things my asset can do - which is great :D

    I think that everyone should be able to adopt this into their workflow, it really encourages the use of ScriptableObjects. ^_^

    Quick question - I could never get RenderStaticPreview to work - does it work with the Object Selector window?
     
  21. raphick

    raphick

    Joined:
    Nov 15, 2016
    Posts:
    365
    Like shown here (
    https://github.com/raphael-ernaelst...review/Editor/Editors/Texture3DEditor.cs#L104) you just need to declare an override of the method with the correct signature in the CustomEditor class and Unity will use its output (whatever Texture2D) as the thumbnail in the project view.

    The thumbnail will be updated everytime the asset s (re)imported, changed or flagged as dirty (then reimported). You can manually flag you object as dirty using the CustomEditor serializedObject member (which is the current viewed asset).

    Just use a private static texture2D as a temporary cache ;)
     
  22. Fydar

    Fydar

    Joined:
    Feb 23, 2014
    Posts:
    69
    The cache is definately a solution to this problem - and I am aware my asset is rendered redundant by a few hours of implimentation and copy-pasting the editor for each of the assets you can to give icons.

    However - caching hundreds of textures is not always ideal when your working on games with many items, and the implementation being a single attribite rather than having to create editors for each asset has its pluses.

    I am aware that a private static texture2d or a static dictionary of sprites to textures can be accomplished.

    I hope to make my asset more appealing by adding other features such as animated icons and the ability to draw custom icons for all files types.

    Thank you @raphick for informing me of the alternate solution to the problem my asset solves - it has given me the motivation and the reason to make something which I hope more people will fimd useful in their workflows.

    If you could be so kind - I don't mean to cause you unnecessary hassle but if I could find out the answer to my question: "does it work with the Object Selector window?" then that would help my greatly.
     
    vedram and rakkarage like this.
  23. raphick

    raphick

    Joined:
    Nov 15, 2016
    Posts:
    365
    I don't know what is the object selector window... Screenshot?
     
  24. Fydar

    Fydar

    Joined:
    Feb 23, 2014
    Posts:
    69
    @raphick I have attached a screenshot of the Object Selector window :)

    Thank you in advanced.
     

    Attached Files:

  25. raphick

    raphick

    Joined:
    Nov 15, 2016
    Posts:
    365
    You should have tried the link ;)

    The "Object Selector" window logically uses the same cache for the asset's thumbnail, so yes

    2017-10-16 11_16_35-Unity 2017.3.0b3 (64bit) - Texture3D preview.png
     
  26. winxalex

    winxalex

    Joined:
    Jun 29, 2014
    Posts:
    166
  27. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    1,089
    What? That's the whole point of this thread. This post has the solution - one that requires no scripting, let alone reflection. To restate the solution, you do the following:
    1. Create a folder directly under Assets called Gizmos (specifically: Assets/Gizmos).
    2. Add your icon texture (typically 128x128 or 256x256) directly to the Gizmos folder and name it "YOURCLASS icon.png".
      • The space is intentional. For a ScriptableObject subclass called "MyDataObject", this would be: Assets/Gizmos/MyDataObject icon.png
    3. Adjust the Import Settings on the icon texture to the following:
      • Texture Type: GUI (Editor \ Legacy)
      • Filter Mode: Point
    With that setup, any asset instance of your "MyDataObject" ScriptableObject subclass will have the specified icon.
     
    CGDever, odoluca and rakkarage like this.
  28. Fydar

    Fydar

    Joined:
    Feb 23, 2014
    Posts:
    69
    I think it would be appropriate to summarise.

    If you want to set the icon of all ScriptableObjects of a type, use either:
    1. Place the icon texture into the "Assets/Gizmos" and name appropriately. (
      Assets/Gizmos/MyScriptableObject icon.png
      )
    2. Assign the icon in the top-left of the ScriptableObjects script inspector.
    If you want a ScriptableObjects icon to be dynamic, depending on the content of it, use either:
    1. Use editor initialisation and hook up all objects that you want to draw a certain icon for using: https://answers.unity.com/questions/1011305/assign-gameobject-icons-more-than-just-one-at-a-ti.html
    2. Create a custom editor and override RenderStaticPreview for each type of ScriptableObject.
    3. Use AssetIcons, and the [AssetIcon] attribute on the field.
     
    TomTrottel, kcfos, SDriver and 3 others like this.
  29. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    1,089
    This has the caveat of not working for scripts contained within assemblies (DLLs).
     
    rakkarage likes this.
  30. winxalex

    winxalex

    Joined:
    Jun 29, 2014
    Posts:
    166

    The point is to reach the goal. Which can be different. With static thing like putting in gizmos you can do limited functionality, e.g you can't have option to change icons per ScriptableObject which is very handy. Second thing if you do package for asset store or simple have organize your stuff, imagine every package messing with Assets/Gizmos overwriting same icons or similar problems....
     
  31. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    1,089
    Important Note: The icon only sets the default icon for a specific ScriptableObject asset class, not all ScriptableObject instances. You can still use other methods to overwrite specific instances within the project.

    Some info:
    • Many Editor Extensions/Assets in the Asset Store already do this. It is the default, simplest, and most-comprehensive way to add an icon to ScriptableObjects such that the icon is properly respected in all use-cases. Assets/Gizmos is a Special Folder and should be used to properly take advantage of the special features it enables.
    • Overwriting icons is a conceivable issue, but you can easily sidestep issues here with better naming. Koreographer has done this for years and we've never had a single bug report about it.
    • If you run into the "icon overwriting" issue, report the fact that you "Can't Assign Unique Default Icons for Two ScriptableObject sub-classes with the Same Name" as a bug to Unity.
      • In the short term, prefix your class name with something asset/namespace/etc. specific.
    I hope this helps.
     
    LaneFox and winxalex like this.
  32. StephenHodgson-Valorem

    StephenHodgson-Valorem

    Joined:
    Mar 8, 2017
    Posts:
    148
    This doesn't work with custom assembly definitions
     
  33. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    1,089
    Hmm... sounds like you should file a bug with Unity on that one. It's possible that the Gizmos approach gets confused when there's a Script file with a GUID that doesn't actually connect to any class instances (as the actual code used by the Editor internally is likely what is produced by the asmdef file). This may fall flat, however, as the icon is identified by class name, rather than GUID... ¯\_(ツ)_/¯

    Have you verified that it works if you remove the asmdef file? That would ensure that the setup is correct and it's the asmdef that breaks things.
     
  34. StephenHodgson-Valorem

    StephenHodgson-Valorem

    Joined:
    Mar 8, 2017
    Posts:
    148
    > Have you verified that it works if you remove the asmdef file? That would ensure that the setup is correct and it's the asmdef that breaks things.

    Yup, no worries, bug report already submitted.
     
    SonicBloomEric likes this.
  35. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,524
    Did this change recently? Does not seem to work. ( 2018.2.0f2 )

    CropperCapture[2].jpg CropperCapture[3].jpg
     
  36. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,697
    Unity 2018 no longer picks it up automatically from Gizmos. You need to manually assign the icon to the script as Eric suggests above. (Inspect the script, click the script's icon in the upper left of the inspector, and click Select Icon.) This works for earlier versions of Unity, too, so you can make an association in, say, Unity 5.6 and export the script as a unitypackage. The icon will still be associated when you import the unitypackage into Unity 2018.
     
    LaneFox likes this.
  37. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    1,089
    Yes, it did. I just tested this in 2018.1.9f1. Whereas previous versions of Unity (presumably up through all 2017 versions) required that icons be directly under the Gizmos directory, regardless of namespace, that is no longer the case.

    As of Unity 2018+, the icons must be placed in a directory hierarchy beneath the Gizmos directory that matches the class' namespace. Therefore, if you have a class MyDataObject defined in namespace Special.Space, then you would need to place the MyDataObject Icon.png texture in the following project directory:
    • Assets/Gizmos/Special/Space/MyDataObject Icon.png
    We now have the following rules for icon placement:
    • Assets/Gizmos/ClassName Icon.png
      • Unity Versions: ?? through 2017.x
      • Namespaces: Ignored.
    • Assets/Gizmos/Your/Namespace/Path/ClassName Icon.png
      • Unity Versions: 2018.1.0+
      • Namespaces: Required: mapped to folders.
    I have verified the above. The change occurred in 2018.1.0.
     
  38. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    1,089
    Are you using Unity 2018.1.0 or newer? If so, have you tried putting the icon in a Gizmos sub-hierarchy that matches the class' namespace? See this post for more details.
     
  39. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,524
    That's great to see namespace support, makes things much easier to manage now. Seems to be working fine, thanks for the information.
     
    SonicBloomEric likes this.
  40. Torqus

    Torqus

    Joined:
    Jan 11, 2016
    Posts:
    5
    Does anyone have any idea how would you use this to set an Icon to a specific folder? Like a Framed picture to the Textures Folder, or a Cog to the Scripts folder.
     
  41. Fydar

    Fydar

    Joined:
    Feb 23, 2014
    Posts:
    69
  42. Ziplock9000

    Ziplock9000

    Joined:
    Jan 26, 2016
    Posts:
    360
    Works perfectly for SO base classes and propagates down to instances in 2018.2
     
  43. GregoryFenn

    GregoryFenn

    Joined:
    Feb 13, 2018
    Posts:
    43
    The July 2014 solution by LightStriker works for me fine except for the annoying caveat that the C# script itself is given the custom icon, as well as each asset created as a ScriptableObject. Ideally I'd want the ScriptableObjects themselves to have an icon, but not the script itself. It's only a minor annoyance though, because you can simply bury the original C# script in other _MyLibrary folders or something out of the way.
     
    gasppol and Roni92pl like this.
  44. Ziplock9000

    Ziplock9000

    Joined:
    Jan 26, 2016
    Posts:
    360
    This works in 2019.2.0f1... If you are trying to do this to existing SO instances.. Click them and "Reimport" and they will update with the icon assigned to the parent script.
     
    Ronsu900, tirarex and Hobbeslionheart like this.
  45. thegamerszone000

    thegamerszone000

    Joined:
    Aug 6, 2020
    Posts:
    1
    Change its Texture Type from "Default" to "Editor GUI and Legacy GUI".
     
    jamesbean likes this.
  46. Tortuap

    Tortuap

    Joined:
    Dec 4, 2013
    Posts:
    137
    That's for ScriptableObject instance as well. But you need a reimport (Right click, Reimport on those scriptable instances or a parent folder), and a graphic refresh (collapse then expand the container folder).
     
    jamesbean likes this.
  47. ostapgum02

    ostapgum02

    Joined:
    Feb 19, 2019
    Posts:
    2
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5.  
    6. [CreateAssetMenu(fileName = "ExamleAttribute", menuName = "Attributes/ExamleAttribute")]
    7. public class ExamleAttribute : ScriptableObject
    8. {
    9.     [ContextMenuItem("Set icon", "SetCustomIcon")]
    10.     public Texture2D icon;
    11.  
    12.     public void SetCustomIcon()
    13.     {
    14.         EditorGUIUtility.SetIconForObject(this, icon);
    15.     }
    16. }
     

    Attached Files:

  48. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    1,089
    @ostapgum02 That's a really clever solution! Nice. That only works for the specific asset instance, though, yes?

    The project-global solution that doesn't require any interaction is outlined here.
     
  49. KillDashNine

    KillDashNine

    Joined:
    Apr 19, 2020
    Posts:
    453
    Thank you to contributors here for getting this working for me.

    Because some information has changed, I will verify here my experience on Unity 2021.3.
    1. Icon folder must be Assets/Gizmos/Full/Class/Namespace/
    2. File name is ClassName Icon.png with a space in the name
    3. Texture Type: Editor GUI and Legacy GUI, Filter Mode: Point (no filter)
    4. Unity restart was needed for Project view thumbs to catch up
    Nothing needs to be manually selected, this will start working when things are right.