Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by mh4 · Aug 16, 2013 at 05:28 AM · guitexturebuttontexture2d

Empty spaces in buttons are detected by mouse

Hello everyone! I have a button that has a texture. However the texture does not fill up the whole button. Thus if my mouse hovers the button but not the texture, the Button.Contains() is called right? My question is: how do I make it such that my function calls if the mouse hovers the textures but not the buttons). I think the picture below gives a better understanding of what I'm trying to say.

Pic: alt text

My Code:

 void OnGUI()
     {
         AbilityButtons();
     }
 
 void AbilityButtons()
     {
         if( buttonToBeDisplayed.Contains(Event.current.mousePosition))
         {
 
             // button pops out
             buttonToBeDisplayed.Set(  buttonToBeDisplayed.x + offset,
                                       buttonToBeDisplayed.y,
                                       buttonToBeDisplayed.width, buttonToBeDisplayed.height);
         }
         
         else
         {
             // button pops in
             buttonToBeDisplayed.Set(  buttonToBeDisplayed.x - offset,
                                       buttonToBeDisplayed.y,
                                       buttonToBeDisplayed.width, buttonToBeDisplayed.height);
         }
         //////////////////////////////////////////////////////////////////////
         
         if( GUI.Button(buttonToBeDisplayed, textureToBeDisplayed))
         {
             ActivatePowers();
         }
     }

unity_ans_q1.jpg (51.0 kB)
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by robertbu · Aug 17, 2013 at 01:30 AM

@alok1974's comments are on the mark. I don't know of a way to get the pixel color at the mouse position of a GUI button. You can implement the button as a texture on a plane in world space. Then the RaycastHit structure return by the Physics.Raycast() will contain a texture coordinate you can use to get the pixel color. Note the texture you get the pixel from does not have to be the texture you use for the button. You can create a mask texture with the same size that defines different areas of your button. You would read from mask texture so you would not have to deal with the shading issues of the real button. The mask can contain more than one color, so you can make different areas of the button trigger different things.

While @alok1974's suggestion of creating a mesh is a good one, all you really need is colliders in the right place.For the specific case of the image in your question, you could also implement it in world space, and use multiple colliders...a box collider for the square part and a sphere collider for the rounded part. A single game object can have multiple colliders as long as they are different types. It cannot have two of the same kind (two box colliders or two sphere colliders for example). But you can always kluge things together using empty child objects for colliders if you need more than one of a specific type.

I answered a question awhile about what you are trying to do, but I cannot find it. Here is an answer to a similar question with a script to get you started.

http://answers.unity3d.com/questions/49912/non-rectangular-buttons.html

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image robertbu · Aug 17, 2013 at 06:10 AM 0
Share

I played a bit and came up with a example. Put the following two images in your Assets folder. Both need to be imported in a format that supports transparency, and the mask image needs to be read/write enabled:

alt text alt text

  • Create a material using the buttons.png texture. The Unlit/Transparent shader would work well.

  • Create a vertical plane and attach the material.

  • Add the following script.

  • Drag and drop the buttons_mask texture onto the tex variable.

  • In the inspector, set the size of the color array to 6 and enter the following colors: (255,0,0), (0,255,0), (0,0,255), (255,255,0), (255,0,255), (0,0,255).


    using UnityEngine; using System.Collections;

    public class Buttons : $$anonymous$$onoBehaviour {

       public Color[] colors;
         public Texture2D tex;
     
         void Update () {
             Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
             RaycastHit hit;
             if (Input.Get$$anonymous$$ouseButtonDown(0) && Physics.Raycast (ray, out hit) && hit.collider.name == "Buttons") {
                 Color pixColor = tex.GetPixelBilinear(hit.textureCoord.x, hit.textureCoord.y);
                 if (pixColor.a < 0.5f) {
                     Debug.Log ("Hit an transparent area");    
                     return;
                 }
                 for (int i = 0; i < colors.Length; i++) {
                     Color c = (colors[i] - pixColor);
                     Vector3 v = new Vector3(c.r,c.g,c.b);
                     if (v.sqr$$anonymous$$agnitude < 0.1f) {
                         Debug.Log ("Button " + i + " pressed");
                     }
                 }
                 
             }
         
         }
     }
    
    
buttons.png (36.3 kB)
buttons_mask.png (11.1 kB)
avatar image whydoidoit · Aug 17, 2013 at 07:05 AM 1
Share

You could do this using GUI by placing the texture in a box and using GetLastRect (or know the rectangle if you aren't using GUILayout) and then work out which coordinates to put into GetPixelBilinear by working out the current mouse position as a proportion of the width and height of that button rectangle.

avatar image robertbu · Aug 17, 2013 at 07:35 AM 0
Share

@whydoidoit - nice idea.
@mh4 - here is a bit of sample code implementing the idea:

 using UnityEngine;
 using System.Collections;
 
 public class Buttons2 : $$anonymous$$onoBehaviour {
     
     public Color[] colors;
     public Texture2D tex;
     public Texture2D tex$$anonymous$$ask;
     private Rect rect;
     private float x = 150;
     private float y = 125;
     
     void Start() {
         rect = new Rect(x,y, tex.width, tex.height);
     }
     
     void OnGUI() {
         Event e = Event.current;
         
         if (e.type == EventType.$$anonymous$$ouseDown && rect.Contains(e.mousePosition)) {
             Debug.Log ("Inside");
             Vector2 v2 = e.mousePosition;
             v2.x -= x;
             v2.y -= y;
             float u = v2.x/rect.width;
             float v = 1.0f - v2.y/rect.height;
             
             Color pixColor = tex$$anonymous$$ask.GetPixelBilinear(u, v);
             if (pixColor.a < 0.5f) {
                 Debug.Log ("Hit an transparent area");    
                 return;
             }
             for (int i = 0; i < colors.Length; i++) {
                 Color c = (colors[i] - pixColor);
                 Vector3 v2b = new Vector3(c.r,c.g,c.b);
                 if (v2b.sqr$$anonymous$$agnitude < 0.1f) {
                     Debug.Log ("Button " + i + " pressed");
                 }
             }            
         }
         GUI.DrawTexture (rect, tex);
     }
 }
avatar image
2
Wiki

Answer by alok1974 · Aug 16, 2013 at 07:23 AM

I am very new to Unity and the awesome forum, but still, I will try to answer. It is possible that there may be better answers than mine but I will answer anyway.

So, the long-winded and hacky way (not even sure if this is possible) would be to query the pixel color of the texture at the mouse position. If it is green (as in your example) then trigger the event else return.

The easier and more efficient way is to create a mesh for the button having the shape of your texture. So if, for example, your button is a triangle, then make a mesh having the exact triangle shape as your texture using a 3D modeling app like max, maya, blender etc. Then apply your image as texture over this mesh. This way, the event is triggered only when the mouse is over the mesh and you do not have to change anything in your code.

I hope it is clear.

Good luck!

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image mh4 · Aug 17, 2013 at 12:31 AM 0
Share

For the long winded way: What if the texture is an image and has multiple colors?

For the easier way: Hmm that sounds interesting but I dont know how to use $$anonymous$$aya, 3D $$anonymous$$ax etc. Lol. $$anonymous$$aybe I can ask a friend to help out with that and we'll see.

Thanks for the input though. Really appreciate it ^_^

avatar image Sajidfarooq · Aug 17, 2013 at 06:34 AM 0
Share

For a newbie, Alok's answer is pretty accurate. Up-voted.

The implementation can be found on Robertbu's answer.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

18 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Making texture cover whole button 1 Answer

Assiging an Image to a Button 1 Answer

Make more buttons appear, on button click. 1 Answer

Update Texture type to GUI during runtime 1 Answer

Null reference exception[SOLVED] 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges