• 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 /
  • Help Room /
avatar image
16
Question by U_Ku_Shu · Nov 01, 2015 at 02:10 PM · c#guiraycast

UI panel without Image component as Raycast target? It is possible?

At the moment I'm using UI panel WITH Image component. Image is invisible. Is it possible to remove image component but mark this object as Raycast target?

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

5 Replies

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

Answer by Statement · Nov 01, 2015 at 03:09 PM

So the GraphicRaycaster work on Graphic objects (see EventSystem, Raycasters).

Image is a MaskableGraphic which is a Graphic, so this is why Image acts a raycast blocker.

Theres Canvas Group (scripting reference) which according to the docs sound like it would do what you ask, but I was not able to get click events without a Graphic attached. For reference, here's the script I used to test if it worked, perhaps I did something wrong etc. It didnt appear to get input without a Graphic anyway. As soon as I add an image etc, it works.

 using UnityEngine;
 using UnityEngine.EventSystems;
 
 public class PrintOnPointerClick : MonoBehaviour, IPointerClickHandler
 {
     void IPointerClickHandler.OnPointerClick(PointerEventData eventData)
     {
         print("Clicked " + name);
     }
 }

Either you have to use any Component that subclasses from Graphic (such as Image, or create your own), or you have to provide a new Raycaster, such as a Physics2DRaycaster or a custom raycaster that extend from BaseRaycaster.

Unfortunately, setting alpha to zero will still cause the quad to be drawn, causing alpha blending which could impact performance on mobile devices. The method I used to try this out was to slide alpha all the way to zero and then use a material which doesn't use the alpha channel, but output a solid color instead. Therefore we can assume that the quad will be rendered, unless the system has a default mode for standard (blank) materials with zero alpha.

However for the GraphicRaycaster to block, the bare minimum is to have a Graphic, and graphics will be rendered. If you subclass Graphic, you'll notice it'll draw a quad on the transform so there seems to be no way out without rendering something, using GraphicRaycaster alone...

Raycasters, then...

Any custom built Raycasters will automatically work with Unitys EventSystem component. All you have to do is to implement the abstract method and property to get going, and possibly override any of the few virtual members. You can also take a look at Unity 5.2 UI open source code to see how the systems interact with each other. If you use a secondary Raycaster that detects your object, then you don't need a Graphic to get the pointer click or block the ray.

 public abstract Camera eventCamera { get; }
 public abstract void Raycast(PointerEventData eventData, List<RaycastResult> resultAppendList);
Comment
Add comment · Show 6 · 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 laurentlavigne · Dec 29, 2015 at 11:10 AM 1
Share

I remember a UT dev mentioning that alpha 0 images don't get drawn but still catch events.

avatar image victorbisaev laurentlavigne · Jan 04, 2016 at 09:36 AM 0
Share

Please clarify what do you mean by "alpha 0 images" as setting Alpha value to "0" for "Color" property of "Image" component still shows draw call in "Frame Debug"? Unity version is 5.3.0f4.

avatar image Statement laurentlavigne · Mar 07, 2016 at 12:40 PM 0
Share

I can't (and won't be bothered to verify) remember which version I personally saw that graphics which had alpha 0 texture on them still were drawn. I replaced the materials shader with one that outputs a solid color to verify that it was happening.

avatar image Doddler · Feb 22, 2016 at 09:47 PM 1
Share

I'm encountering this exact same issue now as well. What I've done is created a class that extends Graphic which overrides the UpdateGeometry function, and then just left it completely blank. It should then receive raycasts without incurring the additional draw call.

avatar image Statement Doddler · Mar 07, 2016 at 12:41 PM 0
Share

"Should"? Does it, or does it not? I would assume you you'd get another draw call because Unity wouldn't know if alpha was used to make the entire quad transparent, depending on shader used.

avatar image pako Doddler · Aug 14, 2020 at 03:01 PM 0
Share

... and over 4 years later... :-)

Good idea! I tried it and it does actually reduce the draw calls! However, the same draw call reduction can now also be achieved by setting the image color alpha to 0 and enabling "Cull Transparent $$anonymous$$esh" on the CanvasRenderer. If I remember well, CanvasRenderer did not expose any components in the Inspector when you wrote this, so it was an excellent idea, thanks!

avatar image
51

Answer by slippdouglas · Mar 20, 2016 at 02:32 AM

After reading over @Statement's incredibly helpful answer, I decided to try making a non-drawing Graphic subclass.  The result was surprisingly simple, and in my testing has worked without problems (descendant-GO components still layout and draw as expected).

The NonDrawingGraphic class:

 using UnityEngine;
 using UnityEngine.UI;
 
 /// A concrete subclass of the Unity UI `Graphic` class that just skips drawing.
 /// Useful for providing a raycast target without actually drawing anything.
 public class NonDrawingGraphic : Graphic
 {
     public override void SetMaterialDirty() { return; }
     public override void SetVerticesDirty() { return; }
     
     /// Probably not necessary since the chain of calls `Rebuild()`->`UpdateGeometry()`->`DoMeshGeneration()`->`OnPopulateMesh()` won't happen; so here really just as a fail-safe.
     protected override void OnPopulateMesh(VertexHelper vh) {
         vh.Clear();
         return;
     }
 }

An optional NonDrawingGraphicEditor class, put in an Editor/ folder in your project, will make sure Unity doesn't show the “Color” and “Material” fields in the Inspector, which we'd rather not see since they don't actually affect anything.

 using UnityEngine;
 using UnityEditor;
 using UnityEditor.UI;
 
 [CanEditMultipleObjects, CustomEditor(typeof(NonDrawingGraphic), false)]
 public class NonDrawingGraphicEditor : GraphicEditor
 {
     public override void OnInspectorGUI ()
     {
         base.serializedObject.Update();
         EditorGUILayout.PropertyField(base.m_Script, new GUILayoutOption[0]);
         // skipping AppearanceControlsGUI
         base.RaycastControlsGUI();
         base.serializedObject.ApplyModifiedProperties();
     }
 }

Usage couldn't be simpler:

alt text


screen-shot-2016-03-19-at-102539-pm.png (6.0 kB)
Comment
Add comment · Show 7 · 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 U_Ku_Shu · Mar 20, 2016 at 04:19 AM 0
Share

Looks like this no need more with comment of @victorbisaev

avatar image slippdouglas · Mar 31, 2016 at 12:22 PM 2
Share

@U_$$anonymous$$u_Shu If I'm understanding you correctly, then yes, @victorbisaev's answer does too solve this problem.  However, one of the most important things I've learned working in the game industry is that rule #1 is to never, ever, ever, ever have the machine do more work than it has to, unless saving the machine work will take your time away from implementing more important things.  I've now solved the problem with a simple solution that doesn't incur performance costs of the Text component's internal logic; therefore there's almost no reason not to use NonDrawingGraphic.

avatar image Ben-BearFish · Apr 26, 2016 at 06:11 PM 1
Share

@slippdouglas I wish we could somehow combine your answer and @Statement 's answer into a super answer. His for being informative and helpful in understanding the underlying issue. And yours for giving a clean script implementation for doing what's needed. Thanks to both of you for both your answers.

avatar image slippdouglas Ben-BearFish · Jul 25, 2016 at 01:53 AM 0
Share

@Ben BearFish: Thanks. ;-)  No need; if you like both his & $$anonymous$$e then just upvote both.  There's no reason why there can't be multiple good answers to a question here on Unity Answers.

avatar image IgorAherne · Mar 28, 2017 at 11:31 PM 0
Share

O$$anonymous$$G! this is a gem. Rewarded 500 reputation!

avatar image ikust · Feb 14, 2018 at 01:12 PM 1
Share

Additionally, If you need a Raycast target that is not a rectangle, you can implement bool Raycast(Vector2 sp, Camera eventCamera) method from Graphic.

Show more comments
avatar image
11

Answer by victorbisaev · Dec 10, 2015 at 04:51 PM

Finally this works well: create "Text" uGUI component inside Canvas, clear its "Text" value and set "Raycast Target" to "true". No extra draw call but clicks are intercepted. I'm not the author for the solution, I've just seen it somewhere in the Internet. Thank you, the author!

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 mtusan · Feb 03, 2016 at 04:45 PM 1
Share

I just figured this out myself as well. But decided to look around if there is a cleaner solution. I'm in the process of optimizing and reducing drawcalls and I confirm that blank text component is not causing any drawcall but still catching input. This is the simplest solution so far...

avatar image guneyozsan · May 31, 2017 at 05:22 PM 0
Share

I can confirm this was the cleanest and simplest solution.

avatar image
4

Answer by petersvp · Jun 18, 2020 at 06:31 PM

This is the only thing you actually need!

 using UnityEngine.UI;
 
 public class RaycastTarget : Graphic 
 {
     public override void SetMaterialDirty() { return; }
     public override void SetVerticesDirty() { return; }
 }
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 guneyozsan · Jun 19, 2020 at 08:29 PM 0
Share

Did you check if this introduces an extra draw call?

avatar image AntonPetrov · Oct 27, 2020 at 08:12 PM 1
Share

@guneyozsan At least in Overdraw mode it is invisible if compared to an Image. Even with Color.alpha != 0.

avatar image
0

Answer by Yiming075 · Apr 18 at 10:47 AM

Tested in Unity 2020.3.18f1. The image with alpha set to 0 will not be drawn.

Comment
Add comment · 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

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

57 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 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 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 avatar image avatar image avatar image

Related Questions

I am trying to close the GUI if its already active and the user clicks 2 Answers

Problem with UI GraphicRaycasting 1 Answer

Bugging ragdoll 1 Answer

How can I make my Raycast ignore my player, but have other player's Raycasts be able to hit it? 1 Answer

Why does FixedUpdate work when Update() doesn't? 2 Answers


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