Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Trying to write a method to return angle between 2 waypoints in 3D space

Discussion in 'Scripting' started by HAMSTAR_RISING, Jan 13, 2019.

  1. HAMSTAR_RISING

    HAMSTAR_RISING

    Joined:
    Jan 20, 2018
    Posts:
    5
    Hi, I have been trying to find some help with a method I am writing. What I am trying to acheive is, as a car moves towards its current waypoint the closer it gets the more the wheels point towards the next waypoint so to create a smooth bezier like curve between the current waypoint and the one after...





    this is the code so far for the method:


    Code (CSharp):
    1.   public float GetAngle(Vector3 vec1, Vector3 vec2, Vector3 vec3)
    2.     {
    3.         float _distanceToWaypoint;
    4.  
    5.         Vector3 _aiCarPosition = this.transform.localPosition;
    6.         Vector3 _waypointP1 = transform.InverseTransformPoint(_waypointList1[_currentWaypoint].position);
    7.         Vector3 _waypointP2 = transform.InverseTransformPoint(_waypointList2[_nextWaypoint].position);
    8.         _distanceToWaypoint =Vector3.Distance(transform.position, _waypointList1[_currentWaypoint].position);
    9.  
    10.  
    11.         vec1 = _aiCarPosition;
    12.         vec2 = _waypointP1;
    13.         vec3 = _waypointP2;
    14.  
    15.         float lengthA = Mathf.Sqrt(Mathf.Pow(vec2.x - vec1.x, 2) + Mathf.Pow(vec2.y - vec1.y,2));
    16.         float lengthB = Mathf.Sqrt(Mathf.Pow(vec3.x - vec2.x,2) + Mathf.Pow(vec3.y - vec2.y, 2));
    17.         float lengthC = Mathf.Sqrt(Mathf.Pow(vec3.x - vec1.x,2) + Mathf.Pow(vec3.y - vec1.y, 2));
    18.  
    19.         float calc = ((lengthA * lengthA) + (lengthB * lengthB) - (lengthC * lengthC)) / (2 * lengthA * lengthB);
    20.  
    21.  
    22.  
    23.         return Mathf.Acos(calc) * Mathf.Rad2Deg / _distanceToWaypoint;
    24.  
    25.  
    26.     }
    27.  
    28.  
    29.     private void ApplySteer()
    30.     {
    31.  
    32.         if (_avoiding) return;
    33.  
    34.  
    35.         foreach (WheelCollider wheel in m_Wheels)
    36.             {
    37.      
    38.                 if (wheel.transform.localPosition.z > 0)
    39.                 _targetSteerAngle = _newSteer;
    40.             }
    41.  
    42.     }
    43.  



    I have 2 issues, first, how do I pass the returned angle into the _newsteer variable in the ApplySteer() method?

    And second is, have I set up the calculation right so the closer to the first waypoint the car gets...the more the wheels will turn towards the next waypoint?

    many thanks in advance for any help or guidence :)
     
    Last edited: Jan 13, 2019
    Antypodish likes this.
  2. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,579
    Welcome to the community.

    Firstly please update post following code tagging
    Using code tags properly

    Then can you please post some screenshot into post, to visualize what you exactly mean.
     
    HAMSTAR_RISING likes this.
  3. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,579
    Well done.
    Btw, you can paste images directly to post. Just for future knowledge :)

    So you want angle between two vectors. Vertical and longer diagonal.
    Unity provides simple solution
    Code (CSharp):
    1. Vector3.Angle ( V1, V2 ) ;
    https://docs.unity3d.com/ScriptReference/Vector3.Angle.html

    Basically you want two vectors, where
    • First one is car to waypoint 1
    • Second one is car to waypoint 2
    From that, you can get nice angle
    Note, in documentaion from provided link, on the bottom, there is also SignedAngle. Which may be more of use to you.
    You basically need use third vector, which is up. See doc.

    If you have both method called in same script, you should be able read returned value, and pass it to ApplySteer as argument. In script where you call GetAngle, I assume you got something
    Code (CSharp):
    1. float angle = GetAngle (...);
    So you may want to add
    Code (CSharp):
    1. ApplySteer ( angle ) ;
    Or something like that.

    Feels so much over complicated to me :)
    I mean you got distance division which is fine. But then you got angles acos etc. Which I don't give my head thinking, what is going on there :p
     
    Last edited: Jan 13, 2019
  4. HAMSTAR_RISING

    HAMSTAR_RISING

    Joined:
    Jan 20, 2018
    Posts:
    5
    Hi, thanks for the reply,
    Yes it is what I put in the brackets that is confusing me:

    Code (CSharp):
    1.     float angle = GetAngle (...);
    2.  
    what do I put in (...); I tried all kinds of things and keeps throwing up an error?

    and for your next point do you mean change my steer method to be like this:

    Code (CSharp):
    1.     private void ApplySteer(angle)
    2.     {
    3.         if (_avoiding) return;
    4.         foreach (WheelCollider wheel in m_Wheels)
    5.             {
    6.    
    7.                 if (wheel.transform.localPosition.z > 0)
    8.                 _targetSteerAngle = angle;
    9.             }
    10.     }
     
  5. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,579
    Yep, just dont forget float next angle.

    You got GetAngle(Vector3 vec1, Vector3 vec2, Vector3 vec3), so it indicates what you need there.
    Also, you should always use meaningful names.

    Is this actually your code?
     
  6. HAMSTAR_RISING

    HAMSTAR_RISING

    Joined:
    Jan 20, 2018
    Posts:
    5
    Hi no, the code is not mine....I have been trying to frankenstein this method together as am not sure how to construct it...I am very new to c# and trying to learn some more complex stuff....I do understand the basics of what i'm trying to do....I just lack the knowledge of how to properly construct the method :(

    so I would write:

    Code (CSharp):
    1.  
    2. float angle = GetAngle (Vector3 vec1, Vector3 vec2, Vector3 vec3);
    and then I can use "angle" to pass into the apply steer method like this:

    Code (CSharp):
    1.         private void ApplySteer(angle)
    2.         {
    3.             if (_avoiding) return;
    4.             foreach (WheelCollider wheel in m_Wheels)
    5.                 {
    6.      
    7.                     if (wheel.transform.localPosition.z > 0)
    8.                     _targetSteerAngle = angle;
    9.                 }
    10.         }
    11.  
     
  7. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,579
    In this case, I can only advise you, go to Learn section, so you can pick up necessary basics knowledge.
    Watch videos and practice them. Good luck.
     
  8. HAMSTAR_RISING

    HAMSTAR_RISING

    Joined:
    Jan 20, 2018
    Posts:
    5
    Ok, thanks for your help. I will try and work it out :)
     
    Antypodish likes this.
  9. TOES

    TOES

    Joined:
    Jun 23, 2017
    Posts:
    134
    Just post the code that gets the right result, its like one line of code while you post 1000 lines of nothing. Christ