• 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 DrakeSwartzy · Mar 16, 2017 at 08:30 PM · c#physicsunity5collider2d

Prefab Collider2D not Recognized as Raycast Collider

Hello everyone :) Here's the situation:

I have a baddy prefab which has two collider components: a simple CapsuleCollider2D used for physics, and a trigger PolygonCollider2D used only for mouse point collisions.

The PolygonCollider2D is updated through an attached script (Baddy.cs) only when needed using:

 if(this.gameObject.GetComponent<PolygonCollider2D>()!=null){
     Destroy(this.gameObject.GetComponent<PolygonCollider2D>());
 }
 this.gameObject.AddComponent<PolygonCollider2D>();
 this.gameObject.GetComponent<PolygonCollider2D>().isTrigger=true;

Yes, this is poor practice, but it get's the job done. It works perfectly: in the scene view of the game I can pause and see that there is indeed a polygon collider on our baddy prefab.

In another attached script (CollisionHandler.cs) we check for a mouse press on our baddy:

 if(MousePress()){
     hit=Physics2D.Raycast(level.mousePoint, Vector2.zero, 0f);
     if(hit&&hit.collider==this.gameObject.GetComponent<PolygonCollider2D>()){
         print("baddy mousePress");
     }
 }

However hit.collider==this.gameObject.GetComponent<PolygonCollider2D>() turns out false, even though I could print both hit.collider and this.gameObject.GetComponent<PolygonCollider2D>() immediately before hand in our if(MousePress()) and have them both defined as:

 D_Prefab(Clone) (UnityEngine.PolygonCollider2D)

They couldn't be different PolygonColliders because there can only be one at a time, since our Baddy script removes and creates the PolygonCollider simultaneously.

Any ideas what could be going wrong?

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
1
Best Answer

Answer by jjcrawley · Mar 17, 2017 at 02:37 AM

Your raycast isn't casting. Well, it is, just not very far. Let me explain, the Physics2D Raycast takes in an origin, a direction, a distance. and a few other titbits. You've written it like this:

 hit=Physics2D.Raycast(level.mousePoint, Vector2.zero, 0f);

Your origin is fine, your direction and distance on the other hand are not. You haven't specified a direction and your casting distance is 0. As a consequence, your ray won't hit anything because it doesn't know which direction to go and it's length is 0, by default distance is Mathf.Infinity. So the cast can't hit anything.

You need to decide which direction to fire in and how far, if you want to specify a distance. This should fix that issue. A few potential issues that may arise afterwards though are detecting the right collider. If the ray hits any collider, it will immediately return that collider, regardless of which collider it is.

Probably the better, and more useful, solution is to make use of a layer mask. This approach involves moving the enemies onto a separate physics layer, so when you do the raycast, you only cast on that layer. A layermask is one of the extra titbits that you can pass to the raycast function:

 hit = Physics2D.Raycast(level.mousePoint, Vector2.Right, 20, LayerMask.GetMask("MyEnemyLayer"));

That should fix any issues that you may run into. The direction, distance and layermask are up to you. Have a peak at the LayerMask documentation for info about how to use it.

Also, make sure that you setup the Physics2D Manager to query triggers, if you don't, the raycast will fire but may ignore the triggers.

Something else that you may want to look into is the mouse down event that Monobehaviours can subscribe to. This is fired whenever the user clicks on a collider, or GUIElement. You don't have to worry about raycasting yourself then, and you don't have to check which collider was hit. If this event is raised on a baddy component, you clicked on a baddy.

Hopefully this helps.

Comment
Add comment · Show 9 · 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 DrakeSwartzy · Mar 18, 2017 at 02:31 PM 0
Share

Unfortunately, this did not resolve the issue. I tried changing the line to hit=Physics2D.Raycast(level.mousePoint, Vector2.right, .5f); and even hit=Physics2D.Raycast(level.mousePoint, Vector3.forward, 1f);. (By the way, the code was working fine when I only created the baddy polygonCollider once on a start function, but after I tried updating the collider through the update function it refuses to work). Also, the issue is not with clicking on the capsuleCollider on accident, since I can click outside of it specifically on the polygonCollider and it still won't work.

avatar image jjcrawley DrakeSwartzy · Mar 18, 2017 at 07:48 PM 1
Share

Don't 'update' the collider, especially if by update you mean destroy and add a new one each update. The physics engine won't have time to check for any ray collisions, as a consequence, it will return the wrong collider info. You only attach in start or awake, and this is done only once. You shouldn't have to constantly attach new components. It may be worth actually adding in the polygon collider to the baddy prefab, this will give you more control over the shape of the click zone, very useful from a design perspective. You won't have to constantly attach a new one in start either. When the start method is called you can cache a reference to the component and check that each update, much safer and more efficient. Something along these lines:

     PolygonCollider2D myCollider;   
         
     void Start()                                                                                                                          
    {                                                                                                                                                 
           myCollider = GetComponent<PolygonCollider2D>();                                                             
                
           //any other start stuff
    }
 

Then for your hit check becomes:

 if(hit.collider == myCollider)
 {
        //do a thing
 }


avatar image DrakeSwartzy · Mar 18, 2017 at 08:00 PM 0
Share

@jjcrawley thanks for your detailed responses. I was afraid of that, you see, because putting new polygonColliders throughout all of my baddy animations would take a long time. There really isn't a way to do this by code? If there is no way to achieve this at run time, what does this line mean? %|971109959_2|%

avatar image jjcrawley DrakeSwartzy · Mar 18, 2017 at 08:39 PM 0
Share

Don't know, the comment code thing was messing around. I think it was supposed to be 'any other start stuff', looks okay on my end just a glitch. You shouldn't have to add polygon colliders to all your baddy animations, just the prefab. Unity uses property paths for their animation stuff, this is just the name of the variable and any other bits and pieces that they need to update that variable at runtime. As a consequence, adding in a new collider to the prefab shouldn't mean that you have to redo all your animations, especially if you're just using sprites for animation. It should, theoretically, just work. Try it and see.

avatar image DrakeSwartzy · Mar 18, 2017 at 09:56 PM 0
Share

Unfortunately, with animations, the polygonCollider component won't update on its own through the animations, it will only retain the first sprites polygonCollider shape for the animation.

avatar image jjcrawley DrakeSwartzy · Mar 18, 2017 at 10:11 PM 1
Share

If you wanted to change its shape then yes, you'll have to animate the collider by hand. Why not use a box collider? The polygon collider would be more expensive to calculate intersections for at runtime, and the box collider should be accurate enough for your clicking needs. Of course though, it won't match the shape of your baddies as perfectly, but most games wouldn't require that level of precision for simple clicks. On top of that, you'd only have to animate the height and width of the collider. When compared to a polygon collider it would be much simpler. Just a thought.

avatar image DrakeSwartzy jjcrawley · Mar 18, 2017 at 11:16 PM 0
Share

@jjcrawley, you would definitely be right in most cases, but unfortunately I definitely need this to be precise. From your experience, do you believe that creating polygonColliders in the animations would bog down the system? Also, can you think of any other methods to achieve what we're trying to do? $$anonymous$$any thanks

Show more comments
avatar image DrakeSwartzy · Mar 19, 2017 at 01:21 PM 0
Share

For future reference, Physics2D.RaycastAll with a layer$$anonymous$$ask helped resolved this situation.

avatar image
0

Answer by Commoble · Mar 16, 2017 at 09:28 PM

First thing I can see is that your hit check reads as false if it doesn't hit the polygon collider, but a raycast will stop at the first collider it hits, so it'll also returns false if it hits some other collider, including your capsule collider on the same object.

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 DrakeSwartzy · Mar 17, 2017 at 12:45 AM 0
Share

If I understand what you're saying, shouldn't the hitTest only consider polygonColliders on the baddy since we're checking hit.collider==this.gameObject.GetComponent<PolygonCollider2D>()

avatar image Commoble DrakeSwartzy · Mar 17, 2017 at 01:57 AM 0
Share

Your raycast can potentially hit ANY collider that exists at that point in space, regardless of which object it's on or what type of collider it is. If the collider it hits is NOT your object's polygon collider, then your if statement will be false.

avatar image DrakeSwartzy · Mar 17, 2017 at 12:47 AM 0
Share

If I had just put hit==this.gameObject then it would consider any type of attached collider, right?

avatar image Commoble DrakeSwartzy · Mar 17, 2017 at 01:58 AM 0
Share

hit.collider.gameObject == this.gameObject, but yes

avatar image DrakeSwartzy · Mar 17, 2017 at 02:11 AM 0
Share

Oops yes good call hit.collider.gameObject @Commoble But still the question remains what is wrong with the code? Shouldn't this work perfectly then since we decided that the code searches for a collision with only the baddy's polygonCollider as intended?

avatar image DrakeSwartzy · Mar 17, 2017 at 02:17 AM 0
Share

By the way the capsuleCollider is not the real issue, I can click outside the capsuleCollider on the PolygonCollider and it still won't work @Commoble

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

9 People are following this question.

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

Related Questions

Need a simple car physics script working on unity 5? 1 Answer

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

why Raycast2D doesn't work properly? 0 Answers

Clamping movement causes jittering 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