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
11
Question by jkh13 · Nov 23, 2013 at 06:22 PM · collisionrigidbodycollidertriggeriskinematic

How to get collision point when using onTriggerEnter

I have a number of colliders attached to isKinematic=true rigidbodies as I do not want physics to affect my objects. I am using triggers to detect collisions between the colliders and this works fine. I was wondering if it is possible to determine the collision point (Vector3) and normal using triggers? onTriggerEnter takes a Collider instead of a Collision as a parameter. If this is not possible what would be the best way to have my objects not being affected by physics in anyway yet be able to detect collisions and the point of collision as well?

Comment
Add comment · Show 5
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 sdgd · Nov 23, 2013 at 06:31 PM 0
Share

I think it is not possible

else I would do it this way:

 Vector3 ColisionPoint(Vector3 sphere1, Vector3 sphere2, float sphere1radius){
     Vector3 Direction = (sphere2 - sphere1).normalized;
     Vector3 ColisionPoint = sphere1 + (Direction * sphere1radius);
     return ColisionPoint;
 }

I made no comments ins$$anonymous$$d I've wrote pretty much self explanatory and I did 1 extra line just not to get confused too much.

if you get any errors don't look at me I've been writing this on the fly.

avatar image TheLivingTree · Nov 23, 2013 at 06:47 PM 0
Share

Using IsTriggerEnter you cannot get collision points you will have to use OnCollisionEnter(Collision c)

avatar image jkh13 · Nov 23, 2013 at 07:29 PM 0
Share

I thought it was not possible to use OnCollisionEnter with triggers? Two is$$anonymous$$inematic rigidbodies cannot collide together so I believe I need to use triggers to start collision detection.

avatar image TheLivingTree · Nov 23, 2013 at 07:39 PM 1
Share

Well I found this: http://forum.unity3d.com/threads/26232-Trigger-collision-contact-point $$anonymous$$ight be the only way

avatar image sdgd · Nov 24, 2013 at 03:01 PM 0
Share

interesting:

Quietus2 said:

You can likely get a more accurate position by using some known items, namely the collider.bounds of the trigger, then bounds.IntersectRay from the rear of the actor's collider.bounds along it's local z axis and finally ray.getpoint.

That should return a vector3 with a closer approximation of where the actor's bounding box intersected the trigger.

In any case, I don't believe that triggers are meant to give you such collision information. They don't need it to serve their function. And if they did it would be a line segment of the two bounding boxes' intersection and not a point.

Likely internally it's just using the standard (and very fast) "is one of the bounding box corners within the other box's volume" intersection tests. Only after that returns true does collision code start doing more expensive and accurate tests. They're not needed for a simple trigger, therefore it opts out at that point.

I'm doing this because I heard at forums old posts get RIP and nolonger available to the community.

so he's knowledge will still be alive here on UA

5 Replies

· Add your reply
  • Sort: 
avatar image
7

Answer by shacharoz · Dec 09, 2014 at 09:08 AM

i accomplished this task using a Raycast upon collision (or colliderEnter) event.

 OnTriggerEnter(Collider other){
 
      RaycastHit hit;
         if (Physics.Raycast(transform.position, transform.forward, out hit))
         {
             Debug.Log("Point of contact: "+hit.point);
         }
 }
 

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 kalibcrone · May 25, 2017 at 05:46 PM 1
Share

This is the method I would use, but this will give you the hit point in world space. You can also get the local point of contact for a specific object by doing the following:

 Vector3 locPos = Vector3.zero;
 RaycastHit hit = default(RaycastHit);
 Ray raycast = new Ray (drawWithObject.position, drawWithObject.transform.forward);
  
 //using a mask so that I can ignore objects I don't want the raycast to hit
  if (Physics.Raycast (raycast, out hit, 1000f, hittable$$anonymous$$ask)) 
          {
              //if pointing at the object you want to get collision point for
              if (hit.transform.gameObject == myObject.gameObject)
              {
                  //have locPos = the local position of the hit point
                  locPos = transform.InverseTransformPoint(hit.point); 
              }
          }
avatar image EarthHobbit · Jan 28 at 07:39 AM 0
Share

In my case, the transform.forward gave the object behind the one hit. I had to update the following code: Physics.Raycast(other.transform.position-other.transform.forward, other.transform.forward, out hit)

avatar image
6

Answer by PiFLYON · Mar 17, 2017 at 10:04 PM

On this topic because of google, hope this will help future users. I used the @Sdgd method, but there is no need to use radius to me, the following code is applied on a "shield" objet. I instantiante an impact prefab (containing particles) at the collision point and tell the bullet to die.

This code is in Monobehaviour of my object, having SphereCollider Component, without Rigidbody as player bullets already have kinematic ones. This can work with any kind of collider I guess (sphere or box). This code is for whom wants to use kinematic rigidbodies with trigger colliders (as OnCollisionEnter() doesn't care about them).

The only part that is doing the job are these two lines (all Vector3s) : tmpDirection = (col.transform.position - myTransf.position); tmpContactPoint = myTransf.position + tmpDirection;

The rest of the code is for context...

     private Vector3 tmpContactPoint;
     private Vector3 tmpDirection;
     private GameObject tmpGamob;
     private Transform myTransf;
 
 void Start() {
         myTransf = transform;
     }
 void OnTriggerEnter(Collider col) {
         if (col.tag !="PlayerBullet") return;
         tmpDirection = (col.transform.position - myTransf.position);
         tmpContactPoint = myTransf.position + tmpDirection;
         col.GetComponent<BulletControl> ().Die ();
         tmpGamob= (GameObject)Instantiate(impactBouclier, tmpContactPoint,Quaternion.identity);
         Destroy (tmpGamob, 0.3f);
     }

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 CrymX · May 27, 2017 at 10:52 PM 5
Share

This is totaly wrong

avatar image christougher · Nov 04, 2017 at 12:51 AM 0
Share

This totally worked great for me! :)

avatar image PiFLYON christougher · Nov 04, 2017 at 01:40 AM 0
Share

Nice ! :-) $$anonymous$$aybe you can upvote my answer :))

avatar image GuardHei · Jun 15, 2018 at 11:54 AM 2
Share

It seems that tempContactPoint is just col.transform.position. Could you please explain more details?

avatar image DageLV · Jan 22, 2020 at 02:52 PM 1
Share

Has errors, undefined values and just doesnt work overall, move along people.

avatar image dev_cwj · Jul 16, 2020 at 06:24 AM 1
Share

This is Completely wrong code.

"A + (B-A) == B"

You should know this:

  1. In Vector3, (A - B) equals (Direction from B to A)

  2. (A + 'Direction from B to A') equals (B)

Therefore 'myTransf.position + tmpDirection' is equals 'col.transform.position'

Check Gizmos or Debug.Log

(RTF$$anonymous$$: https://docs.unity3d.com/$$anonymous$$anual/DirectionDistanceFromOneObjectToAnother.html)

avatar image
4

Answer by graham20 · Feb 16, 2015 at 01:16 PM

Depending on how big your objects are, you might get away with just using other.transform.position. I use this for playing a splash particle effect when my player hits water and it looks pretty good.

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 KarlKarl2000 · Aug 12, 2021 at 02:53 AM 0
Share

I totally forgot about this simple solution.. slaps forehead .. thanks for re$$anonymous$$ding me. This is totally it chief

In my case I needed a detection point of contact for OnTriggerEnter2D, then spawn something at that vector3 position.

avatar image
1

Answer by Bryan-Legend · Feb 04, 2016 at 10:40 PM

Here's my solution. Only works with a box collider.

localCollider.ClosestPointOnBounds(target.transform.position) does an okay job but is AABB based.

         void OnTriggerEnter(Collider target)
         {
             //print("TouchDamage trigger with " + collider.name);
 
             var damageable = target.gameObject.GetComponent<Damageable>();
             if (damageable != null)
             {
                 var localCollider = GetComponent<BoxCollider>();
                 if (localCollider != null)
                 {
                     if (CheckEdge(target, damageable, BottomRightEdge(localCollider)))
                         return;
                     if (CheckEdge(target, damageable, TopRightEdge(localCollider)))
                         return;
                     if (CheckEdge(target, damageable, BottomLeftEdge(localCollider)))
                         return;
                     if (CheckEdge(target, damageable, TopLeftEdge(localCollider)))
                         return;
 
                     CollideWith(target, localCollider.ClosestPointOnBounds(target.transform.position), damageable);
                 }
                 else
                     CollideWith(target, transform.position, damageable);
             }
         }
 
         bool CheckEdge(Collider target, Damageable damageable, Ray edge)
         {
             foreach (var hit in Physics.RaycastAll(edge, edge.direction.magnitude))
             {
                 if (hit.collider == target)
                 {
                     CollideWith(target, hit.point, damageable);
                     return true;
                 }
             }
             return false;
         }
 
         Ray BottomRightEdge(BoxCollider collider)
         {
             var bottomRight = transform.TransformPoint(collider.center + new Vector3(collider.size.x, -collider.size.y, collider.size.z) * 0.5f);
             var topRight = transform.TransformPoint(collider.center + new Vector3(collider.size.x, collider.size.y, collider.size.z) * 0.5f);
             return new Ray(bottomRight, topRight - bottomRight);
         }
 
         Ray TopRightEdge(BoxCollider collider)
         {
             var bottomRight = transform.TransformPoint(collider.center + new Vector3(collider.size.x, -collider.size.y, -collider.size.z) * 0.5f);
             var topRight = transform.TransformPoint(collider.center + new Vector3(collider.size.x, collider.size.y, -collider.size.z) * 0.5f);
             return new Ray(bottomRight, topRight - bottomRight);
         }
 
         Ray BottomLeftEdge(BoxCollider collider)
         {
             var bottomLeft = transform.TransformPoint(collider.center + new Vector3(-collider.size.x, -collider.size.y, collider.size.z) * 0.5f);
             var topLeft = transform.TransformPoint(collider.center + new Vector3(-collider.size.x, collider.size.y, collider.size.z) * 0.5f);
             return new Ray(bottomLeft, topLeft - bottomLeft);
         }
 
         Ray TopLeftEdge(BoxCollider collider)
         {
             var bottomLeft = transform.TransformPoint(collider.center + new Vector3(-collider.size.x, -collider.size.y, -collider.size.z) * 0.5f);
             var topLeft = transform.TransformPoint(collider.center + new Vector3(-collider.size.x, collider.size.y, -collider.size.z) * 0.5f);
             return new Ray(bottomLeft, topLeft - bottomLeft);
         }
 
         void OnDrawGizmosSelected()
         {
             BoxCollider b = GetComponent<BoxCollider>();
             if (b != null)
             {
                 Gizmos.color = Color.red;
                 Gizmos.DrawRay(BottomRightEdge(b));
                 Gizmos.DrawRay(TopRightEdge(b));
                 Gizmos.DrawRay(BottomLeftEdge(b));
                 Gizmos.DrawRay(TopLeftEdge(b));
             }
         }
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
avatar image
0

Answer by triangle4studios · Jul 11, 2021 at 09:24 PM

Surely col.gameObject.transform.position is the simplest solution for the hit point.

To get the normal, Surely these will work for you:

2D -col.gameObject.transform.up

3D -col.gameObject.transform.forward

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 dev_cwj · Jul 12, 2021 at 09:02 AM 0
Share

The hit point in OnTriggerEnter is not equal col.transform.position(col.gameObject.transform.position). Probably you think of a small object with a collider.


Think about it.. If the sphere collider is very large, then the transform.position of the sphere collider will not touch other collider let alone hit point when OnTriggerEnter situation.


So, hit point in OnTriggerEnter, OnCollisionEnter are not equal col.transform.position The real hit point is myCollider, otherCollider's contact point.

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

30 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

Related Questions

Moving kinematic rigidbody trigger against kinematic rigidbody collider 0 Answers

how to check for collison with a navmeshagent 0 Answers

Can't add Rigidbody component because collision prevents it 2 Answers

Collider2D/RigidBody2D not working 1 Answer

Possible to stop collider from "popping" through plane when re-centering? 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