Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 SrBilyon · Sep 19, 2012 at 05:38 AM · raycastaiobstacleavoidance

Raycast Steering Problem

I'm working on a raycast driven obstacle avoidance that will steer characters away from obstructions, but I'm having problems with making the character completely steer away from obstructions.

alt text

With the code I have below, the character is facing away from the obstacles until the feeler rays aren't touching, but now, the character faces right back towards the ray if the raycast hits again instead of staying steered away.

[**Text in Pic**]: The gray line represents the intended direction of the character before obstacle avoidance. The black line represents the direction the character should be steering towards after obstacle avoidance.

The orange line represents one of the feelers detecting a surface, and storing it's normal, which should be applied (trans.forward += hit.normal.normalized * Time.smoothedDeltaTime;)

Figure two represents what the error looks like: the character re-orients itself to face the player (which makes it face the wall again) after steering is done (black line), and repeats what's going on in figure one.

P.S: I am avoiding UnitySteer since I'm not really looking into having to use an outside framework.

I'm pretty sure the problem lies here in this snippet:


 var adjDir = ObstacleAvoidance(character.direction, new Vector3(2f, 1, 2f), character.checkObstacles);
 
 character.targetSpeed = character.maxSpeed;
 
 if (!isSteering)
               character.direction = new Vector3(character.direction.x * character.targetSpeed, character.direction.y , character.direction.z *character.targetSpeed);
           else
               character.direction = new Vector3(adjDir.x, character.direction.y, adjDir.z);
 
           trans.forward = new Vector3(character.direction.x, 0, character.direction.z).normalized * Time.deltaTime; 



Here is all the code I am using:


 Vector3 ObstacleAvoidance(Vector3 dir, Vector3 steering, bool checkObstacles)
     {
         List<Vector3> steeringRays = new List<Vector3>();
         var _holdTheJump = dir.y;
         
         bool left = false;
         bool right = false;
         bool front = false;
         Vector3 adjDirection = dir;
         
         steeringRays.Add(trans.TransformDirection(-steering.x, steering.y, steering.z)); //ray pointed slightly left 
         steeringRays.Add(trans.TransformDirection(steering.x, steering.y, steering.z)); //ray pointed slightly right 
         steeringRays.Add(trans.forward); //ray 1 is pointed straight ahead
         
         RaycastHit hit;
         
         if (checkObstacles )
         {
                 Debug.DrawRay(trans.localPosition, steeringRays[0].normalized * rayLength, Color.cyan);
                 Debug.DrawRay(trans.localPosition, steeringRays[1].normalized * rayLength, Color.cyan);
                 Debug.DrawRay(trans.localPosition, steeringRays[2].normalized * rayLength, Color.cyan);
 
                 if (Physics.Raycast(trans.position, steeringRays[0], out hit, rayLength))
                 {
                     if (hit.collider.gameObject.layer != 13 && (!front && !left))
                     {
                         isSteering = true;
                         front=false; right=false; left=true;
                         Debug.DrawLine(trans.position, hit.point, Color.red);
                         trans.forward += (hit.normal).normalized * Time.smoothDeltaTime;
                         Debug.Log("Steer Left");
                         return trans.forward;
                     }
                 }
                 else                
                 if (Physics.Raycast(trans.position, steeringRays[1], out hit, rayLength))
                 {
                     if (hit.collider.gameObject.layer != 13 && (!front && !left)) //Character layer
                     {
                         Debug.DrawLine(trans.position, hit.point, Color.red);
                         front=false; right=true; left=false;
                         isSteering = true;
                         trans.forward += (hit.normal).normalized * Time.smoothDeltaTime;
                         Debug.Log("Steer Right");
                         return trans.forward;
                     }
                 }
                 else 
                 {
                     isSteering = false;
                     left = false; right = false; front = false;
                     return adjDirection;
                 }
             return adjDirection;
         }
         return adjDirection;
     }
     
     public bool Seek(Vector3 targetPos)
     {        
         var tempDir = (targetPos - trans.position);
         var holdY = character.direction.y;
         
         character.direction = new Vector3(tempDir.x, 0, tempDir.z).normalized;
         character.direction.y = holdY;
         character.speed = character.targetSpeed;
         
         if (character.controller.isGrounded)
             character.jumping = false;
         
         //If not to close, but not to far
         if ((tempDir.magnitude > character.minDistance))   
         {
             //Check for potential pitfalls. Stop if there is a pitfall ahead
             RaycastHit hit;
             
             #region Ground Ahead!
             if (Physics.Raycast(trans.position + trans.forward, Vector3.down, out hit, 10))
             {
                 var adjDir = ObstacleAvoidance(character.direction, new Vector3(2f, 1, 2f), character.checkObstacles);
 
                 character.targetSpeed = character.maxSpeed;
                 
                 if (!isSteering)
                     character.direction = new Vector3(character.direction.x * character.targetSpeed, character.direction.y , character.direction.z *character.targetSpeed);
                 else
                     character.direction = new Vector3(adjDir.x, character.direction.y, adjDir.z);
                 
                 trans.forward = new Vector3(character.direction.x, 0, character.direction.z).normalized * Time.deltaTime; 
             }#endregion
             else
             #region There is a pit!
             {
                 character.targetSpeed = 0; 
 
                  if (!character.jumping)
                 {
                     character.Upward(10);    
                     character.jumping = true;
                 }
             }
             #endregion
 
               return false;
         }
         return true;
     }



steeringproblem!!!!!!!.png (27.1 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

1 Reply

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

Answer by Fattie · Sep 19, 2012 at 06:48 AM

Solved...

It appears you have had a mixup with the NORMAL at a raycast point and the REFLECTION at a raycast point.

To reflect a Vector3, you'll need to get in to this ...

http://docs.unity3d.com/Documentation/ScriptReference/Vector3.Reflect.html

Note ....... I believe you DO NOT NEED either the reflection or normal here here, but let's see how this correction helps.


Here is a long explanation of what "a normal" is particularly WRT raycasts/collisions.

@Sir, I've got a feeling there's a problem with "normal" and/or the terminology

"The orange line represents one of the feelers detecting a surface, and storing it's normal...."

to be clear....

alt text

The "normal" to a surface is the tangent that comes off the surface. On a flat surface it's simply "up" away from the surface. On a curve it's the tangent that sticks off most directly at that point.

(Indeed, in the 3D world, the mesh is made up of triangles of course, each triangle has a normal. Note for example the first image here http://answers.unity3d.com/questions/266972/detecting-mesh-orientation.html (please vote up useful answers you come across! :) ) it shows "the normal" of that one triangle.)

In your diagram. the "normals" TO THE SURFACE would be lines leaving it at right angles. The surface is simply flat, so no matter what point you are talking about the normal is just "straight off it".

alt text

Now when you do a raycast (or collision) Unity will give you "the normal" of the object, at that point.

http://docs.unity3d.com/Documentation/ScriptReference/ContactPoint-normal.html

Note that the incoming angle of the raycast is not related to the normal ...... the normal is just you "the normal" at that point. Looking at the diagram, for all the orange rays, the normal at that point is just the same. (Again, since your brown box is flat the normal simply comes off it at 90 degrees.)

Now differently from that .. when you "normalize" a vector that just means making it have length of one. It is completely unrelated to the "normal" of a surface.

Further, if you meant "normalized" it could be you are taling about the normalized version of the orange line, or the purple line, or some other line !

So when you say "and storing it's normal" I don't know what you are storing.

IF you mean the value returned by this

http://docs.unity3d.com/Documentation/ScriptReference/ContactPoint-normal.html

then that will ALWAYS BE just the purple line I show in the diagram.

So first we have to clarify this before we can figure out the problem!


normal.jpg (48.0 kB)
normalsexplained.jpg (89.9 kB)
Comment
Add comment · Show 8 · 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 SrBilyon · Sep 19, 2012 at 07:01 AM 0
Share

Okay. I believe it was me being confused with ter$$anonymous$$ology. I guess i thought that the normal returned (brace yourself), was a reflection of the raycast hit :D

Yes. I normalized the vector to make it's length one. Nice diagrams! They are really helpful.

avatar image MithosAnnar · Sep 19, 2012 at 07:23 AM 1
Share

Wow fattie you're really helpful!

Are you a paid employee?

Anyway thanks for the wonderful help on this, my enemies pathfinding through trees and rocks and mountains is Working!

avatar image Fattie · Sep 19, 2012 at 07:26 AM 1
Share

LOL no problem $$anonymous$$ithos. Answering questions like this helps me to think.

No unfortunately I have been unemployed for decades, but it's nice of you to say!

avatar image SrBilyon · Sep 19, 2012 at 07:30 AM 0
Share

You'd make a good professor :D

avatar image whydoidoit · Sep 19, 2012 at 07:34 AM 1
Share

I do hope you're an American @fattie - or does the sun go over the yard arm in the morning for you ;) 10am??? I'm with you on the Chardonnay but I try to wait for elevensies...

Show more comments

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

13 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

Related Questions

Obstacle Avoidance 0 Answers

Problems with raycast obstacle avoidance 1 Answer

Keeping an raycasting AI within a patrol area 1 Answer

Raycast AI - Avoiding Obstacles in 2D Topview (Using Velocity) 1 Answer

Unity AI Obstacle Avoidance Help 3 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