Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

DrawGizmo on Tagged Objects

Discussion in 'Editor & General Support' started by zKici, Sep 17, 2018.

  1. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    437
    Hello,

    I would really like to draw a texture for my specific tagged objects in scene, example Enemy.

    This way I can see all the enemies location, as some of them are particles it is hard to know.

    I tried to use a script from the forum, the only issue is it will crash the Scene view if you are in play mode, so I tried using the on Start to turn off the component however then when the play mode is finished it remains off.

    This can be very helpful for building elaborate game levels.. any help will be greatly appreciated,

    here is what I had thus far:

    https://pastebin.com/VnYhF8RE

    I suppose it is not necessary to have these Gizmos in the scene view while in play mode..

    Thank you
     
  2. Burkard

    Burkard

    Joined:
    Feb 22, 2014
    Posts:
    13
    Looks like a bit overkill to create a manager gameobject with a MonoBehaviour class just to check if some class is tagged "Foo" and then apply an icon to its GameObject. It would have to iterate over all the objects in the scene (to FindWithTag).

    Looks a bit less complicated (and less overhead) if you create your class Enemy : Monobehaviour (or even create a super class ClassWithIcon : Monobehaviour, then extend the enemy class Enemy : ClassWithIcon), and use the (Unity) method OnDrawGizmos(){
    Gizmos.DrawIcon(......);
    }.

    Then, in the ClassWithIcon, use the code here:
    https://docs.unity3d.com/ScriptReference/Gizmos.DrawIcon.html

    So, to change the icon based on a private [serialized] variable.

    Or create an interface and use in the classes you want. Not sure right now, but doesn't seem the best choice.

    Hope you find the way, try a little; if it doesn't work after some tries, ask then I can write some code.

    Cheers!
     
  3. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    437
    When it comes to coding and getting down to some complex stuff, honestly I get lost. I try to learn and dissect others codes to learn from and tweak for my own use but it doesn't always work out.

    Appreciate your response and even more so if you could throw out somewhat of a working code then I can tweak it for my own use.. as I am truly stuck with this one,


    It doesn't matter how its done to me as long as everything tagged under Enemy will be visible in scene view.

    Thank you
     
  4. Burkard

    Burkard

    Joined:
    Feb 22, 2014
    Posts:
    13
    1) Download the icon image you want to use in the scene view
    2) Save it in the folder: Assets/Gizmos/ghost-512.png (change the name if you want)
    3) Set the Texture Type from "Default" to "Sprite (2D and GUI)"
    4) Create the tags you want; I'll create 2: "Enemy" and "Treasure"; each one will have a different icon, of course. You can add more later.
    4.1) Download another image icon for the treasures:​
    https://vignette.wikia.nocookie.net/clubpenguin/images/b/b2/Quest_item_Treasure_Chest_icon.png
    4.2) I'll give this image the name "Chest.png" (it is case sensitive!)
    4.3) Repeat step 3 for this icon​
    5) Create a new C# script, and name it whatever you want. I'll use "IconIdentifier.cs" => if you change the name of the file, change the class name too!
    6) Paste the following code:


    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3.  
    4. public class IconIdentifier : MonoBehaviour {
    5.     public static Dictionary<string, string> iconTypes = new Dictionary<string, string>
    6.     {
    7.         { "Enemy", "ghost-512.png" },
    8.         { "Treasure", "Chest.png" },
    9.         // here, add all the other icons you want, following the pattern (each one in a new line):
    10.         // { "TagName", "filename.ext" },
    11.     };
    12.  
    13.     private void OnDrawGizmos()
    14.     {
    15.         if (IconIdentifier.iconTypes.ContainsKey(gameObject.tag))
    16.         {
    17.             Gizmos.DrawIcon(transform.position, IconIdentifier.iconTypes[gameObject.tag], true);
    18.         }
    19.     }
    20.  
    21.     private void OnDrawGizmosSelected()
    22.     {
    23.         Gizmos.color = Color.yellow;
    24.         Gizmos.DrawWireSphere(transform.position, 2f);
    25.     }
    26. }

    7) Create a cube (or whatever gameobject you want), and add the script to it. Change it's tag to Enemy, and Voilà! Look at the Scene view. Create another gameobjects, add the Treasure tag, but DON'T FORGET to add the IconIdentifier script to the objects you want to identify! The easiest way to do this is to create a prefab with the script, then use it.

    8) IMPORTANT:
    8.1) If the icons are too tiny, change the scale as seen here: https://answers.unity.com/questions/760892/gizmosdrawicon-is-it-possible-to-scale-the-icon.html
    8.2) The documentation says: "This function does not get called if the component is collapsed in the inspector"
    https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnDrawGizmos.html
    8.2.1) This is useful if you want to hide the icons - just collapse the script in the Inspector.
    8.3) The function OnDrawGizmosSelected is optional, you can use it to view in the Scene which object is selected in the Hierarchy window. You can also change it's color and radius.​

    9) As you add new icons in the Gizmos folder, create tags and add them in the "iconTypes" dictionary, after the line 8 of the IconIdentifier class.

    10) You can download the whole project here (just open the SampleScene.unity and scale the icons up):
    https://drive.google.com/file/d/1e4paSlp2oiRs1mQSRdQFTwmouZZr1C5g/view?usp=sharing

    11) And here is a preview of what you'll get:
     
    zKici likes this.
  5. Burkard

    Burkard

    Joined:
    Feb 22, 2014
    Posts:
    13
    If you need more, just ask.
    Hope you like!
     
  6. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    437
    Amazing thank you it works!

    I do have a slight change hoping you can help me with,

    Could I specify different textures for different enemy names, i have about 10 enemy names and it would be really neat if they all had their own scene texture to distinguish between one another.

    If its too much to ask for no worries you've already helped a ton.

    I spent over 2 days trying to figure this out...

    Thank you!!! :)
     
  7. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    437
    I changed your script to this: https://pastebin.com/6yqrzKZ7

    it works but i feel it is not complete, let me know what i should do different :)

    I coulnd't figure out how to check for Enemy tag only etc.
     
  8. Burkard

    Burkard

    Joined:
    Feb 22, 2014
    Posts:
    13
    You did it right. However, it probably won't work if you instantiate the enemies by script (because it adds the " (clone)" suffix).

    You could do it this way:
    1) Check if it is a tagged object and if this tag has an icon;
    2) If it has an icon, check if this object's name has a specific icon;
    2.1) If it has a specific icon, use it;
    2.2) If it doesn't (it's neither a fireball, nor a lightningBolt, for example), show a "generic" enemy icon.​
    3) I will use this icons for fireball and lightning:
    https://images.vexels.com/media/use...e4b0-yellow-lightning-bolt-icon-by-vexels.png
    https://cdn0.iconfinder.com/data/ic...tasy_Spell_Magic_Dungeons_Roleplay-05-512.png

    4) Save them to the Gizmos folder (don't forget to rename the files properly => "fireball.png" and "lightningbolt.png");

    5) Try this code (see the generic enemy using the ghost icon, and the others using their respective icons):
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3.  
    4. public class IconIdentifier : MonoBehaviour {
    5.     public static Dictionary<string, string> iconTypes = new Dictionary<string, string>
    6.     {
    7.         { "Enemy", "ghost-512.png" },
    8.         { "Treasure", "Chest.png" },
    9.         // here, add all the other icons you want, following the pattern (each one in a new line):
    10.         // { "TagName", "filename.ext" },
    11.     };
    12.     public static Dictionary<string, string> enemyNames = new Dictionary<string, string>
    13.     {
    14.         { "fireball", "fireball.png" },
    15.         { "lightningbolt", "lightningbolt.png" },
    16.     };
    17.  
    18.     private void OnDrawGizmos()
    19.     {
    20.         if (IconIdentifier.iconTypes.ContainsKey(gameObject.tag))
    21.         {
    22.             string icon = IconIdentifier.iconTypes[gameObject.tag];
    23.             if (IconIdentifier.enemyNames.ContainsKey(gameObject.name.ToLower().Replace("(clone)","")))
    24.             {
    25.                 icon = enemyNames[gameObject.name.ToLower().Replace("(clone)", "")];
    26.             }
    27.  
    28.             Gizmos.DrawIcon(transform.position,icon, true);
    29.         }
    30.     }
    31.  
    32.     private void OnDrawGizmosSelected()
    33.     {
    34.         Gizmos.color = Color.yellow;
    35.         Gizmos.DrawWireSphere(transform.position, 2f);
    36.     }
    37. }
    38.  
    Keep coding! :)

    [edit]: here is the screenshot:
     
  9. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    437
    Perfect,

    Thank you very much.

    You should release this as an asset newbies like me could use it :)


    Normally when I instantiate my enemies they all get renamed to what they are (same name) just different parents depending on levell, this works well for my game
     
    Burkard likes this.