- Home /
Custom Icon on ScriptableObject
Hey guys, i doing some itens for my game make the development easer, i wish add custom icons to my itens, which are ScriptableObjects, how i can do this? i know the trick of put the icon on Gizmo folder with the same name as the script, but the icons should be different for different itens which have the same script
Answer by spilat12 · Feb 25, 2019 at 03:22 AM
Hi there @arkadsgames. You can do it without the Gizmos folder. Just select the ScriptableObject script (not the ScriptableObject asset!) and select its icon in the Inspector. That will change that script's icon as well as all icons of respective ScriptableObject assets!
Additionally, you can visit this thread for more info, it has lots of gold in it: https://forum.unity.com/threads/custom-scriptableobject-icons-thumbnail.256246/
Hi, i'm working on a cards game where there are different "roles". Every scriptable object needs to have a custom image. How do i do it?
Hi there, my answer quite literally answers your question. Just click the icon in the Inspector and you will be able to set it just like that.
This works. However, existing instances of the ScriptableObject were not updated (i.e. it only applied to the ScriptableObject assets I created after changing the icon). Didn't try restarting Unity though, so that may fix that issue.
Yes, restarting Unity make it update the icon of the scriptable object instances (not just the script).
Answer by dragon_script · Apr 26, 2020 at 10:05 PM
Hi, i'm working on a cards game where there are different "roles". Every scriptable object needs to have a custom image. How do i do it?
Add an 'image' property. From your game, load it into the UI.
Looks like there's a new API for this in 2021.2!
https://docs.unity.cn/2021.2/Documentation/ScriptReference/EditorGUIUtility.SetIconForObject.html
Answer by TustinJimberlake · Nov 03, 2021 at 01:32 AM
There is a new API for this in 2021.2 that might do what you are looking for. It even tells you how to make it persistent across script reloads ;)
https://docs.unity.cn/2021.2/Documentation/ScriptReference/EditorGUIUtility.SetIconForObject.html
Edit: Okay so it turns out this is really really jank. As far as I can tell, Unity doesn't want you to instance these icons. On compile/load, all of the assets will be set to the same icon, even if you properly set each one individually. You have to inspect them by clicking on them individually to get them to update to their true icons. If anyone has a solution to this please let me know :/
Answer by BgBg · May 31 at 06:36 PM
Hi.
It's possible!
Short history:
I downloaded and explore this project: https://blog.unity.com/technology/isometric-2d-environments-with-tilemap
I noticed that in this project, icons from scriptable objects are displayed in the inspector:
After, i found some editor script, and edited him for my project.
I don't understand how it works, but it works. =)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using System.Reflection;
using Object = UnityEngine.Object;
[CustomEditor(typeof(item_so),true)]
[CanEditMultipleObjects]
public class ItemSOEditor : Editor
{
private item_so item { get { return (target as item_so); } }
public override Texture2D RenderStaticPreview(string assetPath,Object[] subAssets,int width,int height)
{
if(item.standart_item_struct.item_icon!=null)
{
Type t = GetType("UnityEditor.SpriteUtility");
if(t!=null)
{
MethodInfo method = t.GetMethod("RenderStaticPreview",new Type[] { typeof(Sprite),typeof(Color),typeof(int),typeof(int) });
if(method!=null)
{
object ret = method.Invoke("RenderStaticPreview",new object[] { item.standart_item_struct.item_icon,Color.white,width,height });
if(ret is Texture2D)
return ret as Texture2D;
}
}
}
return base.RenderStaticPreview(assetPath,subAssets,width,height);
}
private static Type GetType(string TypeName)
{
var type = Type.GetType(TypeName);
if(type!=null)
return type;
if(TypeName.Contains("."))
{
var assemblyName = TypeName.Substring(0,TypeName.IndexOf('.'));
var assembly = Assembly.Load(assemblyName);
if(assembly==null)
return null;
type=assembly.GetType(TypeName);
if(type!=null)
return type;
}
var currentAssembly = Assembly.GetExecutingAssembly();
var referencedAssemblies = currentAssembly.GetReferencedAssemblies();
foreach(var assemblyName in referencedAssemblies)
{
var assembly = Assembly.Load(assemblyName);
if(assembly!=null)
{
type=assembly.GetType(TypeName);
if(type!=null)
return type;
}
}
return null;
}
}