Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
9
Question by Novodantis 1 · Dec 08, 2010 at 12:00 AM · collisionrigidbodytriggerpassthrough

Detecting which Collider involved in Trigger 'Collision'

My issue is mainly down to this: OnCollisionEnter() returns a Collision. OnTriggerEnter() returns a Collider.

With the former, I have been able to detect a Collider (bullet) hitting my rigidbody collection of colliders (player). Using Collision.contacts is the only way I've been able to discern which collider in my Player object has taken the hit, which is important for damage allocation.

However, in the case of what I shall call AlternativeBullet, I am using a trigger rather than a collider (because I don't want the collision to have a physics knockback). All I've got when a trigger touches part of the Player is the collider (ie. Trigger) that touched, not any actual location data such as Collision gives.

This is deceptively simple-looking. I originally expected the script calling OnCollisionEnter() or whatever to only be called on the object who's collider is being hit, but this is not the case. It is called on the object with the rigidbody, ie. the master Player object to which these GameObjects with colliders are parented. Hence the need to use Collision.contacts to find which collider actually got hit.

Can anyone suggest any alternative ways of finding which collider was 'hit' by the trigger version of the bullet. Or, better yet, a way of nullifying a collision the physics engine has already registered so the bullet won't have any momentum effect.

Thanks!

Comment
Add comment · Show 1
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 Proclyon · Dec 13, 2010 at 05:06 PM 0
Share

Well this is really silly, all answers here are really usefull and I'd vote them all up but I'd be casting myself down. So how about this, I vote up the people I think gave a good answer, ignore the bounty and you tell us what solution worked for you so the Q&A is usefull for everyone ? Good question btw

4 Replies

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

Answer by Statement · Dec 10, 2010 at 05:29 PM

You could get slightly better bullet code by doing a RayCast or a SphereCast every update, from the previous location to the current location of the bullet. Think of the sphere cast like a thick ray cast. Casting a ray or a sphere from one point to another reduce odd physics behaviour like tunneling and is probably easier to fix than your current situation.

You can then obtain an exact or approximate position where the ray or sphere hit the object.

You then don't need any collider at all on your bullet prefab.

You can send a custom message on bullet hit such as this psuedo code (just after the ray test):

if (hitOther)
{
  other.SendMessage("OnBulletHit", bulletHit,
                     SendMessageOptions.DontRequireReciever);
}

And your player/enemy could have a function that handle this gracefully such as:

function OnBulletHit(bulletHit : BulletHit) { health -= bulletHit.damage; BloodEffects(bulletHit.position); PlayHitSound(bulletHit.position);

 if (bulletHit.isRadioactive)
 {
      AddRadiationSickness();
 }
 if (health <= 0 && bulletHit.damage > 25)
 {
      ExplodeIntoGibParts();
 } 

}

You'd have to design your BulletHit structure or class yourself but that shouldn't pose any problems. You need to consider what data is important describing a bullet hit event and put that in your type.

  • Note that there is a bug (unless they fixed that) where the SphereCast doesn't register hits with a Trigger. So if you need to be able to hit triggers with your bullets you should probably use RayCast instead.
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 Proclyon · Dec 11, 2010 at 12:07 AM 0
Share

Does that bug apply to capsule cast aswell?

avatar image Statement · Dec 11, 2010 at 12:45 AM 0
Share

Yes, I think so. I think it applies to those "volume" casts that were introduced. It's a shame really, they would be so useful.

avatar image Proclyon · Dec 13, 2010 at 05:04 PM 0
Share

I couldn't agree more! I was jumping through the roof when I saw capsulecast. Looked like something I wish I had a year ago. And then after a lot of "trying to figure out how to use it" I got strange results and kept trying. Still doing that...

avatar image Novodantis 1 · Dec 14, 2010 at 05:49 PM 0
Share

Excellent suggestion; and I did consider raycasting a little after writing this question. But wouldn't RaycastHit return a collider in much the same way as OnCollision? I suppose being more like OnTrigger means it might return the right one. I shall experiment and let you know what fixes it, thanks!

avatar image Statement · Dec 15, 2010 at 01:34 AM 0
Share

Yes it does return the collider it hit, but it also gives the point of collision. Raycasts wouldn't do much use if you couldn't deduce where the ray hit something. It is useful for pushing the object exactly where you hit it, if you are dealing with physics for example.

Show more comments
avatar image
2

Answer by Facundo · Dec 10, 2010 at 04:31 PM

OnTriggerEnter seems to return the right collider (actual descendant hit) in a test project I did: https://www.yousendit.com/download/cEd0K2VucVhsUi92Wmc9PQ

May I be overlooking something important in your specification?

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 Proclyon · Dec 13, 2010 at 05:07 PM 0
Share

Yeah I thought so aswell. I never had a problem with getting colliders. A collision can not really occur without 2 objects being registered any way you look at it. So even if you can just "handle" one you just read the other.

avatar image Novodantis 1 · Dec 14, 2010 at 05:36 PM 0
Share

Curiously, OnTriggerEnter() does indeed, yes. However, if you switch from Trigger to Collider and modify the function accordingly, you should find it now only registers the root collider (just tried with that project you kindly supplied). This is what caused me to move the code onto the root object rather than the bullet, hence this current rather strange situation!

avatar image
2

Answer by Proclyon · Dec 11, 2010 at 04:44 PM

You can prevent the rigidbody problem by destroying the rigidbody using a character controller in the physics section instead and use the OnControllerColliderHit function.

void OnControllerColliderHit(ControllerColliderHit cch)
{
    Debug.Log("cch hit");   
}

Doing this detects the start of a collision using the regular physics but the energy (kinetic) will not be transfered from object A to B. However the collision occurs is registered and a property of cch.collider DOES exist and can be retrieved giving you the collider you need without getting punched in the chest by some force

P.S.

I just tested this in a new project I whipped up for the question. It worked without a problem. Let me know if you get any results that differ. I can't promise I didn't forget something stupid (Humans tend to do that :/)

Comment
Add comment · Show 1 · 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 Novodantis 1 · Dec 14, 2010 at 05:58 PM 0
Share

This is an intriguing workaround, but unbeknownst to ye, the object in question is an airship capable of rolls and turns, so I fear swapping the rigidbody for a character controller wouldn't be feasible. However, if you can link me to the example, I'd be interested to check it out.

avatar image
0

Answer by lucianv · Oct 20, 2016 at 10:25 AM

To see which sub-collider hit the trigger object you might use the following method:

Create a simple script to use on each sub collider called ColliderProxy

 using UnityEngine;
 using System.Collections;
 
 public class ColliderProxy : MonoBehaviour
 {
     public enum ColliderId { None, Body, Range };
     public ColliderId colliderId = ColliderId.None;
 
     public delegate void ColliderDelegate(ColliderId collider);
     public event ColliderDelegate OnTriggerEnterByCollider;
 
     void OnTriggerEnter(Collider other)
     {
         if (OnTriggerEnterByCollider != null)
         {
             OnTriggerEnterByCollider(colliderId);
         }
     }
 }

On the main object you'll have something like this:

 using UnityEngine;
 using System.Collections;
 
 public class MainObjectScript : MonoBehaviour
 {
     public GameObject objectWithSubcollider1;
     public GameObject objectWithSubcollider2;
     
     void Awake()
     {
         objectWithSubcollider1.GetComponent<ColliderProxy>().OnTriggerEnterByCollider += OnTriggerEnterByCollider;
         objectWithSubcollider2.GetComponent<ColliderProxy>().OnTriggerEnterByCollider += OnTriggerEnterByCollider;
     }
 
     void OnTriggerEnterByCollider(ColliderProxy.ColliderId colliderId)
     {
         Debug.Log(“OnTriggerEnter by collider: " + colliderId);
     }
 }

Just set the ids for the subcolliders after attaching the script. On the scene object holding the trigger collider you'll need to have a rigidbody. On the subobjects holding the subcolliders you'll have just the colliders, if the main object doesn't have a rigidbody. If the main object has a rigidbody, the subobjects might need one as well. A no gravity, kinematic one.

Comment
Add comment · Show 4 · 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 Entretoize · May 12, 2017 at 02:21 PM 0
Share

I don't understand because you can't add a script to a collider, so where do you put the first script ?

avatar image lucianv · May 12, 2017 at 02:37 PM 0
Share

@Gregory2fs The first script, the proxy, should be added to each of the gameobjects representing the parts of the whole object, which also contain a collider component (that was what i meant by subcolliders - children gameobjects of the main gameobject, with coliders attached) It should route the collision messages to the script attached on the main gameobject with an id of the child gameobject that triggered the collision.

avatar image Entretoize lucianv · May 12, 2017 at 03:47 PM 0
Share

O$$anonymous$$, then if I have a single gameobject with several boxcollider inside there's no solution ? Or I need to create several sub gameobject with a collider inside.

avatar image lucianv Entretoize · May 13, 2017 at 06:15 AM 0
Share

@Gregory2fs This method requires a child empty gameobject for each collider needed. The child gameobjects might need other components too, like a rigidbody, and the colliderproxy script with the desired id.

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

2 People are following this question.

avatar image avatar image

Related Questions

RigidBody - GameObject moves but mesh stays! 1 Answer

Rigidbody Version of RotateAround 2 Answers

The trigger enter detect fast moving object more accurate 2 Answers

Trigger between 2 kinematic bodies not firing? -1 Answers

OnTriggerEnter is not working! I have tried absolutely everything I can think of. 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