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
1
Question by diegonv · Jan 29, 2021 at 10:37 PM · raycastdirectionpoint

Get direction inside OnCollisionEnter

alt textHi. Im having trouble getting the exit point of imaginary ray. I have a proyectile which impacts against a spaceship (3D) and if gets heavy damage i want to show a explosion geting out from the contrary direction of the impact.

alt text

I use OnColliderEnter(Collider col) from the proyectile, to get the contact point (the red point, see image A.png) which is col.contacts[0].point. I need the yellow point. I thought in raycasting the target collider col.collider.Raycast() with a ray from away against the contact point. But for it i need the direction vector (the green arrow).


Im tried doing something like this:

 Vector3 _direction = (col.contacts[0].point - transform.position).normalized;
 Vector3 _away_point = col.contacts[0].point + _direction * 1000f;

But i get weird directions, see second image. I think its because trasform.position is modified after the impact is done (so the proyectile bounces and changes its position) but before OnCollisionEnter is called. Im tried with transform.forward but its the same problem

Its the complete code: Vector3 _direction = (col.contacts[0].point - transform.position).normalized; Vector3 _away_point = col.contacts[0].point + _direction * 1000f;

 Ray _ray = new Ray(_away_point, -_direction);
 RaycastHit _rh;
     
 if(col.collider.Raycast(_ray, out _rh, 1500f))
 {
     //_rh.point is the needed point
     //i need too the direction so i can assign it to the efect
 }


a.png (4.0 kB)
b.png (15.6 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
1

Answer by jackmw94 · Jan 30, 2021 at 12:01 AM

Good question!

I don't think the information you have in front of you currently is enough to figure out this information so what else can we know..
It sounds like your bullets are using physics and therefore will have rigidbodies on them, so we can get the rigidbody off the collider's gameobject which has access to it's physical state including things such as velocity.

Now given the point at which the bullet hit and it's velocity - which is a vector direction - we can go about figuring out where the other side of the space ship would be. Instead of trying to find a way to raycast through the ship and find the point at which we leave it, this will be a lot easier if we raycast from a point far enough the other side of the ship pointing back in.

Say ships can't be any larger than 20 units / meters:

 private Vector3? FindBulletExit(Transform hitObjectTransform, Vector3 bulletHitPoint, Vector3 bulletVelocity, float maxObjectSize = 20)
 {
     // hit object transform is the ship itself
     // max object size is how far we're going to start our ray, from the bullet hit point
     
     Vector3 rayOrigin = bulletHitPoint + bulletVelocity.normalized * maxObjectSize;
     
     // we start our ray in the direction of the velocity, at distance specified by maxObjectSize
     // it's directed in the opposite direction to that in which the bullet was travelling
     Ray ray = new Ray(rayOrigin, -bulletVelocity);
     
     // your IDE might tell you to refactor this to the non-alloc version
     // this will only happen once a ship's lifetime so not much gain but no harm in doing it
     var bulletExitPointHits = Physics.RaycastAll(ray);
     float closestHitDistance = float.MaxValue;
     int closestHitIndex = -1;
 
     for (var index = 0; index < bulletExitPointHits.Length; index++)
     {
         var raycastHit = bulletExitPointHits[index];
         if (raycastHit.transform == hitObjectTransform)
         {
             // this hit has hit ship, is it the closest?
             float hitDistance = (raycastHit.point - bulletHitPoint).magnitude;
             if (hitDistance < closestHitDistance)
             {
                 // if yes, set this as new closest
                 closestHitDistance = hitDistance;
                 closestHitIndex = index;
             }
         }
     }
 
     if (closestHitIndex == -1)
     {
         Debug.LogError($"FindBulletExit could not find opposite side of object {hitObjectTransform.gameObject} at {maxObjectSize}m from hit");
         // if none of our hits hit the transform we specified we'll have to return null
         // make sure you handle this possibility where you call this code
         return null;
     }
 
     // this is the point on the other side of the gameobject
     // the direction of the explosion will be the same direction as the bullet velocity
     return bulletExitPointHits[closestHitIndex].point;
 }


We use RaycastAll instead of Raycast because there might be multiple points at which the line running through your object might re-enter your object. Such as if there was a large barrelled gun on your ship, you wouldn't want the exit explosion to come out of the barrel, rather the hull which will be the closer hit.

I haven't tested this code, half because I am lazy and half because it's there for you to see the process. If you're struggling to debug problems involving vectors and directions, I don't blame ya, humans aren't all that good at looking at 3 floating point numbers and figuring out how that relates to another set of 3 floating point numbers in 3D space. SO unity give us the ability to write our own gizmos. Just like you have Start, Awake and Update - monobehaviours also provide functions called OnDrawGizmos and OnDrawGizmosSelected which allow us use of the Gizmos library. From here you can draw cubes, spheres, lines, etc that will show up in your scene during edit / play mode. Seeing the intensions of your code in actual space is so damn useful when writing any code like this - if the code doesn't work then use these to solve it!

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 diegonv · Jan 30, 2021 at 01:44 AM 0
Share

Thanks for your time. I will try those gizmos, i used them once, but i forget it. I will have it in $$anonymous$$d for other things. The problem was getting the direction of the proyectile inside OnCollisionEnter. Tried transform.forward, transform.position, rigidbody velocity, but they are all modified after impact. (so doing something like Vector3 rayOrigin = bulletHitPoint + bulletVelocity.normalized * maxObjectSize; i get the direcction after impact (rotated)


I found the solution saving a copy of transform.forward (proyectile) 1 frame before, using a coroutine. I found another coroutine from the base class where i can put the line without creating another. I think its the only way, anyways no worries, it runs ok

avatar image jackmw94 diegonv · Jan 30, 2021 at 10:54 AM 0
Share

Good workaround! If you find this gets a bit messy then an alternative could be to make your bullets triggers only. This is only applicable if they don’t need to bump into things, if they only need the collider to detect when they hit their target. This will mean that when it does hit it won’t bounce of the hull of the ship and therefore its direction, either forward or velocity, will be accurate. There is a check box on the collider to set it as a trigger and then change your bullet collision detection to “OnTriggerEnter” instead of “OnColliderEnter” :)

avatar image
0

Answer by diegonv · Jan 29, 2021 at 11:02 PM

Im resolved it by using a coroutine like this:

private IEnumerator asd() { while(true){ _previous_direction = transform.forward; yield return null; } }


It seems to save the direction before physics, but im not sure if always. And every proyectile will have one more coroutine running. If anyone knows a better way please write

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

156 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 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 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

raycast position & directions 1 Answer

How to get the direction vector given a point and rotation? 1 Answer

bullets fly to the wrong direction in specific situations 0 Answers

Make a pointer arrow that shows where player will go 1 Answer

Vector direction for a reticle 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