NodeCanvas Forums › Support › How to set icon for custom task?
Tagged: task custom icon
Greetings all!
I’m trying to figure out how to use custom icons for my custom tasks. I see there is an attribute that NodeCanvas uses for the internal node types and that’s how it sets the Icon, but this method doesn’t seem usable externally as it doesn’t use the attribute parameter as a path to a texture inside the project.
How can I use a custom icon for my custom tasks without modifying the underlying Task.cs source code to add a setter to the icon parameter?
Thanks!
Will
Hello Will,
To set a custom icon for your tasks you indeed need to use the Icon attribute with the name of the icon. Please note that the icon has to be in a “Resources” named folder in your project for it to be used by the attribute.
Let me know if that works for you.
Thanks!
Join us on Discord: https://discord.gg/97q2Rjh
Hi Gavalakis! Thanks for replying!
I actually made a small change to the CanvasCore/Framework/Runtime/Tasks/Task.cs file here:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
if ( _icon == null ) { var iconAtt = this.GetType().RTGetAttribute<ParadoxNotion.Design.IconAttribute>(true); _icon = iconAtt != null ? TypePrefs.GetTypeIcon(iconAtt, this) : null; // 2022-07-25 - Will Poillion - Added ability to use Asset path for icon. if (_icon == null && iconAtt != null) { _icon = UnityEditor.AssetDatabase.LoadAssetAtPath<Texture>(iconAtt.iconName); } if ( _icon == null ) { _icon = new object(); } } |
I have my icons organized outside of my Resources folder for organization purposes. Rather than have to stick to that folder this allows loading of a texture anywhere in the project.
Of course it’s up to you but that might be a good addition to the codebase. I can’t see any downside to adding this extra code as worse case scenario it just doesn’t find anything.
Thanks!
Will
Hello again,
Alright. I’ve added something similar, however I did so in the TypePrefs.GetTypeIcon method for consistency.
Cheers!
Join us on Discord: https://discord.gg/97q2Rjh
Excellent! While creating some other tasks, I ended up making another change to Task.cs . I modified the access for the icon property so I could override it based on values in the children:
public virtual Texture2D icon
For example I have a IsFacingDirection ConditionTask and I override the icon based on the setting:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public override Texture2D icon { get { if (leftIcon == null) leftIcon = UnityEditor.AssetDatabase.LoadAssetAtPath<Texture2D>("Assets/Sprites/UI/BehaviorTreeIcons/Pathing/DarkIsFacingLeftIcon.png"); if (rightIcon == null) rightIcon = UnityEditor.AssetDatabase.LoadAssetAtPath<Texture2D>("Assets/Sprites/UI/BehaviorTreeIcons/Pathing/DarkIsFacingRightIcon.png"); if (direction == Direction.Left) return leftIcon; else return rightIcon; } } /// Private reference to left/right icon textures private Texture2D leftIcon; private Texture2D rightIcon; |
The icon doesn’t update immediately if the value is changed, but that’s ok. I’m sure you have texture caching done in the background. I just wanted to let you know about this use-case. If possible to make the icon refresh somehow that would be nice, but again it’s not worth a performance hit.
Thank you for your support, Gavalakis. You created an amazing product, and is truly one of the best designed assets I have come across. I will be using this for years to come. I really appreciate it!
Hello again Will. Sorry for the late reply due to August and thank you for your kind feedback!
Your previous suggestion is now part of the live version. Unfortunately I did not add your latest one regarding the virtual method with the automatic refresh because that would indeed have a performance hit instead of the icons being cached.
Thank you!
Join us on Discord: https://discord.gg/97q2Rjh
No problem Gavalakis! I perfectly understand about the caching. I just wanted to let you know my use case.
I already upgraded and am making using of your change. I must re-iterate that you have a really special product here and I’m so happy I switched from BehaviorDesigner. Thanks again!