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. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice
Dismiss Notice
Join us on Dec 8, 2022, between 7 am & 7 pm EST, in the DOTS Dev Blitz Day 2022 - Q&A forum, Discord, and Unity3D Subreddit to learn more about DOTS directly from the Unity Developers.

Debug.DrawArrow()

Discussion in 'Made With Unity' started by AnomalusUndrdog, Apr 16, 2011.

  1. AnomalusUndrdog

    AnomalusUndrdog

    Joined:
    Jul 3, 2009
    Posts:
    1,539
    Did you ever wish there was a Debug.DrawArrow()? I did. Now I made one and I'd like to share it with you guys.

    This is useful for showing debug of a direction.

    Visualizing head and camera rotation:




    Visualizing spawn points:




    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public static class DrawArrow
    6. {
    7.     public static void ForGizmo(Vector3 pos, Vector3 direction, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    8.     {
    9.         Gizmos.DrawRay(pos, direction);
    10.        
    11.         Vector3 right = Quaternion.LookRotation(direction) * Quaternion.Euler(0,180+arrowHeadAngle,0) * new Vector3(0,0,1);
    12.         Vector3 left = Quaternion.LookRotation(direction) * Quaternion.Euler(0,180-arrowHeadAngle,0) * new Vector3(0,0,1);
    13.         Gizmos.DrawRay(pos + direction, right * arrowHeadLength);
    14.         Gizmos.DrawRay(pos + direction, left * arrowHeadLength);
    15.     }
    16.  
    17.     public static void ForGizmo(Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    18.     {
    19.         Gizmos.color = color;
    20.         Gizmos.DrawRay(pos, direction);
    21.        
    22.         Vector3 right = Quaternion.LookRotation(direction) * Quaternion.Euler(0,180+arrowHeadAngle,0) * new Vector3(0,0,1);
    23.         Vector3 left = Quaternion.LookRotation(direction) * Quaternion.Euler(0,180-arrowHeadAngle,0) * new Vector3(0,0,1);
    24.         Gizmos.DrawRay(pos + direction, right * arrowHeadLength);
    25.         Gizmos.DrawRay(pos + direction, left * arrowHeadLength);
    26.     }
    27.  
    28.     public static void ForDebug(Vector3 pos, Vector3 direction, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    29.     {
    30.         Debug.DrawRay(pos, direction);
    31.        
    32.         Vector3 right = Quaternion.LookRotation(direction) * Quaternion.Euler(0,180+arrowHeadAngle,0) * new Vector3(0,0,1);
    33.         Vector3 left = Quaternion.LookRotation(direction) * Quaternion.Euler(0,180-arrowHeadAngle,0) * new Vector3(0,0,1);
    34.         Debug.DrawRay(pos + direction, right * arrowHeadLength);
    35.         Debug.DrawRay(pos + direction, left * arrowHeadLength);
    36.     }
    37.     public static void ForDebug(Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    38.     {
    39.         Debug.DrawRay(pos, direction, color);
    40.        
    41.         Vector3 right = Quaternion.LookRotation(direction) * Quaternion.Euler(0,180+arrowHeadAngle,0) * new Vector3(0,0,1);
    42.         Vector3 left = Quaternion.LookRotation(direction) * Quaternion.Euler(0,180-arrowHeadAngle,0) * new Vector3(0,0,1);
    43.         Debug.DrawRay(pos + direction, right * arrowHeadLength, color);
    44.         Debug.DrawRay(pos + direction, left * arrowHeadLength, color);
    45.     }
    46. }
    47.  
    The code works very much like DrawRay(), at the very least, it requires a position and direction. To specify length, multiply a number to your direction vector.
     
    qiqiqi, gooby429, sheano and 73 others like this.
  2. RichBosworth

    RichBosworth

    Joined:
    May 26, 2009
    Posts:
    325
    I think this forum needs a "Like" button.
     
    gooby429, Plazmin, dawaadcw and 12 others like this.
  3. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,520
    Thanks, it is very useful.
     
    omelchor likes this.
  4. cupsster

    cupsster

    Joined:
    Apr 14, 2009
    Posts:
    363
    Thank You.
     
    omelchor likes this.
  5. zine92

    zine92

    Joined:
    Nov 13, 2010
    Posts:
    1,347
    Thanks very much. Trying it now.
     
    omelchor likes this.
  6. calebhc

    calebhc

    Joined:
    Feb 11, 2013
    Posts:
    12
    Works like a charm! Thanks
     
    omelchor likes this.
  7. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    Agree
     
    Deleted User likes this.
  8. john-essy

    john-essy

    Joined:
    Apr 17, 2011
    Posts:
    464
    Amazing Thankyou
     
  9. XiaoHong

    XiaoHong

    Joined:
    Jun 2, 2013
    Posts:
    2
    Very useful for debugging. Using this to show the speed of my units.
     
  10. Nikolay-Lezhnev

    Nikolay-Lezhnev

    Joined:
    Nov 8, 2012
    Posts:
    6
    Thank you for your script.
    Version with 4-rays arrow ends - useful for 2D:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public static class DrawArrow
    6. {
    7.     public static void ForGizmo (Vector3 pos, Vector3 direction, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    8.     {
    9.         Gizmos.DrawRay (pos, direction);
    10.         DrawArrowEnd(true, pos, direction, Gizmos.color, arrowHeadLength, arrowHeadAngle);
    11.     }
    12.  
    13.     public static void ForGizmo (Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    14.     {
    15.         Gizmos.DrawRay (pos, direction);
    16.         DrawArrowEnd(true, pos, direction, color, arrowHeadLength, arrowHeadAngle);
    17.     }
    18.  
    19.     public static void ForDebug (Vector3 pos, Vector3 direction, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    20.     {
    21.         Debug.DrawRay (pos, direction);
    22.         DrawArrowEnd(false, pos, direction, Gizmos.color, arrowHeadLength, arrowHeadAngle);
    23.     }
    24.  
    25.     public static void ForDebug (Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    26.     {
    27.         Debug.DrawRay (pos, direction, color);
    28.         DrawArrowEnd(false, pos, direction, color, arrowHeadLength, arrowHeadAngle);
    29.     }
    30.    
    31.     private static void DrawArrowEnd (bool gizmos, Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    32.     {
    33.         Vector3 right = Quaternion.LookRotation (direction) * Quaternion.Euler (arrowHeadAngle, 0, 0) * Vector3.back;
    34.         Vector3 left = Quaternion.LookRotation (direction) * Quaternion.Euler (-arrowHeadAngle, 0, 0) * Vector3.back;
    35.         Vector3 up = Quaternion.LookRotation (direction) * Quaternion.Euler (0, arrowHeadAngle, 0) * Vector3.back;
    36.         Vector3 down = Quaternion.LookRotation (direction) * Quaternion.Euler (0, -arrowHeadAngle, 0) * Vector3.back;
    37.         if (gizmos) {
    38.             Gizmos.color = color;
    39.             Gizmos.DrawRay (pos + direction, right * arrowHeadLength);
    40.             Gizmos.DrawRay (pos + direction, left * arrowHeadLength);
    41.             Gizmos.DrawRay (pos + direction, up * arrowHeadLength);
    42.             Gizmos.DrawRay (pos + direction, down * arrowHeadLength);
    43.         } else {
    44.             Debug.DrawRay (pos + direction, right * arrowHeadLength, color);
    45.             Debug.DrawRay (pos + direction, left * arrowHeadLength, color);
    46.             Debug.DrawRay (pos + direction, up * arrowHeadLength, color);
    47.             Debug.DrawRay (pos + direction, down * arrowHeadLength, color);
    48.         }
    49.     }
    50. }
    51.  
    $test.png
     
    Vincent13122, GAS, tosiabunio and 5 others like this.
  11. ocimum

    ocimum

    Joined:
    Apr 19, 2015
    Posts:
    12
    Thanks, works great!
     
  12. Bomadeno

    Bomadeno

    Joined:
    Jul 9, 2012
    Posts:
    2
    Sometimes you don't want arrows on the end of the line, you want them 50 % (or any %) along the line. If so, this modification lets you do that:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. /// <summary>
    4. /// Based on  https://forum.unity3d.com/threads/debug-drawarrow.85980/
    5. /// </summary>
    6. public static class DrawArrow
    7. {
    8.     public static void ForGizmo(Vector3 pos, Vector3 direction, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f, float arrowPosition = 0.5f)
    9.     {
    10.         ForGizmo(pos, direction, Gizmos.color, arrowHeadLength, arrowHeadAngle, arrowPosition);
    11.     }
    12.  
    13.     public static void ForGizmo(Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f, float arrowPosition = 0.5f)
    14.     {
    15.         Gizmos.color = color;
    16.         Gizmos.DrawRay(pos, direction);
    17.         DrawArrowEnd(true, pos, direction, color, arrowHeadLength, arrowHeadAngle, arrowPosition);
    18.     }
    19.  
    20.     public static void ForDebug(Vector3 pos, Vector3 direction, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f, float arrowPosition = 0.5f)
    21.     {
    22.         ForDebug(pos, direction, Color.white, arrowHeadLength, arrowHeadAngle, arrowPosition);
    23.     }
    24.  
    25.     public static void ForDebug(Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f, float arrowPosition = 0.5f)
    26.     {
    27.         Debug.DrawRay(pos, direction, color);
    28.         DrawArrowEnd(false, pos, direction, color, arrowHeadLength, arrowHeadAngle, arrowPosition);
    29.     }
    30.     private static void DrawArrowEnd(bool gizmos, Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f, float arrowPosition = 0.5f)
    31.     {
    32.         Vector3 right = (Quaternion.LookRotation(direction) * Quaternion.Euler(arrowHeadAngle, 0, 0) * Vector3.back) * arrowHeadLength;
    33.         Vector3 left = (Quaternion.LookRotation(direction) * Quaternion.Euler(-arrowHeadAngle, 0, 0) * Vector3.back) * arrowHeadLength;
    34.         Vector3 up = (Quaternion.LookRotation(direction) * Quaternion.Euler(0, arrowHeadAngle, 0) * Vector3.back) * arrowHeadLength;
    35.         Vector3 down = (Quaternion.LookRotation(direction) * Quaternion.Euler(0, -arrowHeadAngle, 0) * Vector3.back) * arrowHeadLength;
    36.  
    37.         Vector3 arrowTip = pos + (direction*arrowPosition);
    38.  
    39.         if (gizmos)
    40.         {
    41.             Gizmos.color = color;
    42.             Gizmos.DrawRay(arrowTip, right);
    43.             Gizmos.DrawRay(arrowTip, left);
    44.             Gizmos.DrawRay(arrowTip, up);
    45.             Gizmos.DrawRay(arrowTip, down);
    46.         }
    47.         else {
    48.             Debug.DrawRay(arrowTip, right, color);
    49.             Debug.DrawRay(arrowTip, left, color);
    50.             Debug.DrawRay(arrowTip, up, color);
    51.             Debug.DrawRay(arrowTip, down, color);
    52.         }
    53.     }
    54. }
    55.  
     
  13. conceptfac

    conceptfac

    Joined:
    Feb 15, 2018
    Posts:
    23
    error CS0103: The name `DrawArrow' does not exist in the current context
     
  14. VRARDAJ

    VRARDAJ

    Joined:
    Jul 25, 2017
    Posts:
    18
    This is great work! I've added to it a bit. I wanted to encapsulate everything OnDrawGizmos within this one class so that other classes can use all drawable capabilities (including handles) without having to implement OnDrawGizmos.

    I needed to utilize a singleton pattern instead of static. Rather than call DrawArrow from anywhere, I add it to an empty object in-scene and let everyone call its singleton instance (see http://wiki.unity3d.com/index.php/Singleton).

    This way, DrawArrow can call OnDrawGizmos. To manage rerendering, I created a dictionary of lines to be drawn. Memory allocation is heavier this way, but I figure I only need this for a few lines at a time.

    With this in place, labels to display arrow magnitude are much easier.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEditor;
    4. using System.Collections.Generic;
    5.  
    6. public class DrawArrow : Singleton<DrawArrow>
    7. {
    8.     Dictionary<string, DebugLineData> linesToDraw;
    9.     List<string> keysToUpdate;
    10.  
    11.     private void Awake()
    12.     {
    13.         linesToDraw = new Dictionary<string, DebugLineData>();
    14.         keysToUpdate = new List<string>();
    15.     }
    16.  
    17.     public void ForGizmo(Vector3 pos, Vector3 direction, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    18.     {
    19.         Gizmos.DrawRay(pos, direction);
    20.  
    21.         Vector3 right = Quaternion.LookRotation(direction) * Quaternion.Euler(0, 180 + arrowHeadAngle, 0) * new Vector3(0, 0, 1);
    22.         Vector3 left = Quaternion.LookRotation(direction) * Quaternion.Euler(0, 180 - arrowHeadAngle, 0) * new Vector3(0, 0, 1);
    23.         Gizmos.DrawRay(pos + direction, right * arrowHeadLength);
    24.         Gizmos.DrawRay(pos + direction, left * arrowHeadLength);
    25.     }
    26.  
    27.     public void ForGizmo(Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    28.     {
    29.         Gizmos.color = color;
    30.         Gizmos.DrawRay(pos, direction);
    31.  
    32.         Vector3 right = Quaternion.LookRotation(direction) * Quaternion.Euler(0, 180 + arrowHeadAngle, 0) * new Vector3(0, 0, 1);
    33.         Vector3 left = Quaternion.LookRotation(direction) * Quaternion.Euler(0, 180 - arrowHeadAngle, 0) * new Vector3(0, 0, 1);
    34.         Gizmos.DrawRay(pos + direction, right * arrowHeadLength);
    35.         Gizmos.DrawRay(pos + direction, left * arrowHeadLength);
    36.     }
    37.  
    38.     public void ForGizmoWithMagnitude(string key, Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    39.     {
    40.         DebugLineData lineData = new DebugLineData();
    41.         lineData.drawing = true;
    42.         lineData.pos = pos;
    43.         lineData.direction = direction;
    44.         lineData.color = color;
    45.         lineData.arrowHeadLength = arrowHeadLength;
    46.         lineData.arrowHeadAngle = arrowHeadAngle;
    47.  
    48.         if (!linesToDraw.ContainsKey(key))
    49.             linesToDraw.Add(key, lineData);
    50.         else linesToDraw[key] = lineData;
    51.     }
    52.  
    53.     private void ForGizmoWithMagnitudeInternal(DebugLineData lineData)
    54.     {
    55.         Gizmos.color = lineData.color;
    56.         Gizmos.DrawRay(lineData.pos, lineData.direction);
    57.  
    58.         Vector3 right = Quaternion.LookRotation(lineData.direction) * Quaternion.Euler(0, 180 + lineData.arrowHeadAngle, 0) * new Vector3(0, 0, 1);
    59.         Vector3 left = Quaternion.LookRotation(lineData.direction) * Quaternion.Euler(0, 180 - lineData.arrowHeadAngle, 0) * new Vector3(0, 0, 1);
    60.         Gizmos.DrawRay(lineData.pos + lineData.direction, right * lineData.arrowHeadLength);
    61.         Gizmos.DrawRay(lineData.pos + lineData.direction, left * lineData.arrowHeadLength);
    62.         Vector3 midPoint = lineData.pos + 0.5f * lineData.direction + new Vector3(0, 0.1f, 0);
    63.         string magnitude = lineData.direction.magnitude.ToString();
    64.         Handles.Label(midPoint, magnitude);
    65.     }
    66.  
    67.     public void ForDebug(Vector3 pos, Vector3 direction, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    68.     {
    69.         Debug.DrawRay(pos, direction);
    70.  
    71.         Vector3 right = Quaternion.LookRotation(direction) * Quaternion.Euler(0, 180 + arrowHeadAngle, 0) * new Vector3(0, 0, 1);
    72.         Vector3 left = Quaternion.LookRotation(direction) * Quaternion.Euler(0, 180 - arrowHeadAngle, 0) * new Vector3(0, 0, 1);
    73.         Debug.DrawRay(pos + direction, right * arrowHeadLength);
    74.         Debug.DrawRay(pos + direction, left * arrowHeadLength);
    75.     }
    76.     public void ForDebug(Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    77.     {
    78.         Debug.DrawRay(pos, direction, color);
    79.  
    80.         Vector3 right = Quaternion.LookRotation(direction) * Quaternion.Euler(0, 180 + arrowHeadAngle, 0) * new Vector3(0, 0, 1);
    81.         Vector3 left = Quaternion.LookRotation(direction) * Quaternion.Euler(0, 180 - arrowHeadAngle, 0) * new Vector3(0, 0, 1);
    82.         Debug.DrawRay(pos + direction, right * arrowHeadLength, color);
    83.         Debug.DrawRay(pos + direction, left * arrowHeadLength, color);
    84.     }
    85.  
    86.  
    87.     private void OnDrawGizmos()
    88.     {
    89.         if (linesToDraw != null && linesToDraw.Count > 0)
    90.         {
    91.             foreach (KeyValuePair<string, DebugLineData> lineDataPair in linesToDraw)
    92.                 if (lineDataPair.Value.drawing)
    93.                 {
    94.                     ForGizmoWithMagnitudeInternal(lineDataPair.Value);
    95.                     keysToUpdate.Add(lineDataPair.Key);
    96.                 }
    97.  
    98.             for (int i = 0; i < keysToUpdate.Count; i++)
    99.             {
    100.                 DebugLineData lineData = linesToDraw[keysToUpdate[i]];
    101.                 lineData.drawing = false;
    102.                 linesToDraw[keysToUpdate[i]] = lineData;
    103.             }
    104.  
    105.             if (keysToUpdate.Count > 0)
    106.                 keysToUpdate.Clear();
    107.         }
    108.     }
    109. }
    110.  
    111. public struct DebugLineData
    112. {
    113.     public bool drawing;
    114.     public Vector3 pos;
    115.     public Vector3 direction;
    116.     public Color color;
    117.     public float arrowHeadLength;
    118.     public float arrowHeadAngle;
    119. }
    120.  
     
  15. methusalah999

    methusalah999

    Joined:
    May 22, 2017
    Posts:
    598
    You will find all built-in gizmos, written in the Debug.DrawLine style in the DebugPlus asset, currently in beta.

    See here !
     
  16. viruseg

    viruseg

    Joined:
    Jul 8, 2017
    Posts:
    9
    Added Handles support
    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3.  
    4. public static class DrawArrow
    5. {
    6.     public static void ForHandle(in Vector3 pos, in Vector3 direction, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    7.     {
    8.         Arrow(TargetType.Handle, pos, direction, Handles.color, arrowHeadLength, arrowHeadAngle);
    9.     }
    10.  
    11.     public static void ForHandle(in Vector3 pos, in Vector3 direction, in Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    12.     {
    13.         Arrow(TargetType.Handle, pos, direction, color, arrowHeadLength, arrowHeadAngle);
    14.     }
    15.    
    16.     public static void ForGizmo(in Vector3 pos, in Vector3 direction, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    17.     {
    18.         Arrow(TargetType.Gizmo, pos, direction, Gizmos.color, arrowHeadLength, arrowHeadAngle);
    19.     }
    20.  
    21.     public static void ForGizmo(in Vector3 pos, in Vector3 direction, in Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    22.     {
    23.         Arrow(TargetType.Gizmo, pos, direction, color, arrowHeadLength, arrowHeadAngle);
    24.     }
    25.  
    26.     public static void ForDebug(in Vector3 pos, in Vector3 direction, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    27.     {
    28.         Debug.DrawRay(pos, direction);
    29.         Arrow(TargetType.Debug, pos, direction, Gizmos.color, arrowHeadLength, arrowHeadAngle);
    30.     }
    31.  
    32.     public static void ForDebug(in Vector3 pos, in Vector3 direction, in Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    33.     {
    34.         Debug.DrawRay(pos, direction, color);
    35.         Arrow(TargetType.Debug, pos, direction, color, arrowHeadLength, arrowHeadAngle);
    36.     }
    37.  
    38.     private static void Arrow(TargetType targetType, in Vector3 pos, in Vector3 direction, in Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
    39.     {
    40.         var right = Quaternion.LookRotation(direction) * Quaternion.Euler(arrowHeadAngle, 0, 0) * Vector3.back * arrowHeadLength;
    41.         var left  = Quaternion.LookRotation(direction) * Quaternion.Euler(-arrowHeadAngle, 0, 0) * Vector3.back * arrowHeadLength;
    42.         var up    = Quaternion.LookRotation(direction) * Quaternion.Euler(0, arrowHeadAngle, 0) * Vector3.back * arrowHeadLength;
    43.         var down  = Quaternion.LookRotation(direction) * Quaternion.Euler(0, -arrowHeadAngle, 0) * Vector3.back * arrowHeadLength;
    44.         var end   = pos + direction;
    45.         Color colorPrew;
    46.        
    47.         switch (targetType)
    48.         {
    49.             case TargetType.Gizmo:
    50.                 colorPrew = Gizmos.color;
    51.                 Gizmos.color = color;
    52.                 Gizmos.DrawRay(pos, direction);
    53.                 Gizmos.DrawRay(end, right);
    54.                 Gizmos.DrawRay(end, left);
    55.                 Gizmos.DrawRay(end, up);
    56.                 Gizmos.DrawRay(end, down);
    57.                 Gizmos.color = colorPrew;
    58.                 break;
    59.            
    60.             case TargetType.Debug:
    61.                 Debug.DrawRay(end, right, color);
    62.                 Debug.DrawRay(end, left, color);
    63.                 Debug.DrawRay(end, up, color);
    64.                 Debug.DrawRay(end, down, color);
    65.                 break;
    66.            
    67.             case TargetType.Handle:
    68.                 colorPrew = Handles.color;
    69.                 Handles.color = color;
    70.                 Handles.DrawLine(pos, end);
    71.                 Handles.DrawLine(end, end + right);
    72.                 Handles.DrawLine(end, end + left);
    73.                 Handles.DrawLine(end, end + up);
    74.                 Handles.DrawLine(end, end + down);
    75.                 Handles.color = colorPrew;
    76.                 break;
    77.         }
    78.     }
    79.    
    80.     private enum TargetType
    81.     {
    82.         Gizmo, Debug, Handle
    83.     }
    84. }
    85.  
     
    Last edited: Aug 30, 2020
    JAMiller likes this.
  17. illinar

    illinar

    Joined:
    Apr 6, 2011
    Posts:
    840
    It's 2020, please add this feature to Unity.
    Gizmos.DrawArrow()
    Debug.DrawArrow()
    !!!
     
  18. blackjlc

    blackjlc

    Joined:
    Oct 29, 2017
    Posts:
    2
    Based on the work of Bomadeno, added support for drawing arrows between two points
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. /// <summary>
    4. /// Based on  https://forum.unity3d.com/threads/debug-drawarrow.85980/
    5. /// </summary>
    6. public static class DrawArrow
    7. {
    8.     public static void ForGizmo(Vector3 pos, Vector3 direction, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f, float arrowPosition = 0.5f)
    9.     {
    10.         ForGizmo(pos, direction, Gizmos.color, arrowHeadLength, arrowHeadAngle, arrowPosition);
    11.     }
    12.  
    13.     public static void ForGizmoTwoPoints(Vector3 from, Vector3 to, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f, float arrowPosition = 0.5f)
    14.     {
    15.         ForGizmoTwoPoints(from, to, Gizmos.color, arrowHeadLength, arrowHeadAngle, arrowPosition);
    16.     }
    17.  
    18.     public static void ForGizmo(Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f, float arrowPosition = 0.5f)
    19.     {
    20.         Gizmos.color = color;
    21.         Gizmos.DrawRay(pos, direction);
    22.         DrawArrowEnd(true, pos, direction, color, arrowHeadLength, arrowHeadAngle, arrowPosition);
    23.     }
    24.  
    25.     public static void ForGizmoTwoPoints(Vector3 from, Vector3 to, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f, float arrowPosition = 0.5f)
    26.     {
    27.         Gizmos.DrawLine(from, to);
    28.         Vector3 direction = to - from;
    29.         DrawArrowEnd(true, from, direction, color, arrowHeadLength, arrowHeadAngle, arrowPosition);
    30.     }
    31.  
    32.     public static void ForDebug(Vector3 pos, Vector3 direction, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f, float arrowPosition = 0.5f)
    33.     {
    34.         ForDebug(pos, direction, Color.white, arrowHeadLength, arrowHeadAngle, arrowPosition);
    35.     }
    36.  
    37.     public static void ForDebug(Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f, float arrowPosition = 0.5f)
    38.     {
    39.         Debug.DrawRay(pos, direction, color);
    40.         DrawArrowEnd(false, pos, direction, color, arrowHeadLength, arrowHeadAngle, arrowPosition);
    41.     }
    42.     private static void DrawArrowEnd(bool gizmos, Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f, float arrowPosition = 0.5f)
    43.     {
    44.         Vector3 right = (Quaternion.LookRotation(direction) * Quaternion.Euler(arrowHeadAngle, 0, 0) * Vector3.back) * arrowHeadLength;
    45.         Vector3 left = (Quaternion.LookRotation(direction) * Quaternion.Euler(-arrowHeadAngle, 0, 0) * Vector3.back) * arrowHeadLength;
    46.         Vector3 up = (Quaternion.LookRotation(direction) * Quaternion.Euler(0, arrowHeadAngle, 0) * Vector3.back) * arrowHeadLength;
    47.         Vector3 down = (Quaternion.LookRotation(direction) * Quaternion.Euler(0, -arrowHeadAngle, 0) * Vector3.back) * arrowHeadLength;
    48.  
    49.         Vector3 arrowTip = pos + (direction * arrowPosition);
    50.  
    51.         if (gizmos)
    52.         {
    53.             Gizmos.color = color;
    54.             Gizmos.DrawRay(arrowTip, right);
    55.             Gizmos.DrawRay(arrowTip, left);
    56.             Gizmos.DrawRay(arrowTip, up);
    57.             Gizmos.DrawRay(arrowTip, down);
    58.         }
    59.         else
    60.         {
    61.             Debug.DrawRay(arrowTip, right, color);
    62.             Debug.DrawRay(arrowTip, left, color);
    63.             Debug.DrawRay(arrowTip, up, color);
    64.             Debug.DrawRay(arrowTip, down, color);
    65.         }
    66.     }
    67. }
     
  19. Neopolitans

    Neopolitans

    Joined:
    Sep 2, 2013
    Posts:
    2
    This is all the stuff not many care about. So I came to this thread looking for answers on how to do this. I couldn't fully figure out the mathematics at first and this thread lead me to reading more on Quaternions & Vectors as Directions. Some maths I had to pick up elsewhere when I didn't know it or recall it. This stuff is pretty cool and I want to leave something here for those who can't spot some of the maths and can't tell what's going on.

    Some quick things to know for those who don't know what's going on yet also want cool arrow gizmo stuff:

    Getting a Direction from two known Vector Points is: Direction = EndVector - StartVector

    This provides the difference between the start and end point for Unity do more maths with.
    Getting a Point along a distance of a vector is: PointAlongLine = Start + (Direction * Distance)
    Adding Direction multiplied by Distance to the start vector gives us the desired point along the line between the Start and End vectors because we're adding a fraction of the difference between the two vectors.
    Getting a Point from a Direction is: End = Start + (Direction [normalized] * distance) [a, b]
    This gives us the direct position to work with as we're adding the normalized direction of the arrow multiplied by the distance. Useful for changing a position and a direction to two positions[c] for DrawLine() in Gizmos, Handles and Debug namespaces.

    a. Getting a point from a direction is simplified to [End = Origin + Direction] if you already normalized and multiplied by distance.
    b. Distance is normally between 0f and 1f. It's possible to go beyond but this will draw the arrow off the line.
    c. Using positions can be frivolous to some but others who start out with vector maths in Unity may know positions.

    Method Values
    Vector3 a - Start Position (e.g. gameObject.transform.position)
    Vector3 b - End Position
    float arrowheadAngle - Angle between arrowhead lines
    float arrowheadDistance - Distance to draw the arrow between the start and end.
    float arrowheadLength - Length of the arrowhead lines


    2D Gizmo Arrow Method
    Code (CSharp):
    1.     private void DrawArrow(Vector3 a, Vector3 b, float arrowheadAngle, float arrowheadDistance, float arrowheadLength)
    2.     {
    3.         // Get the Direction of the Vector
    4.         Vector3 dir = b - a;
    5.  
    6.         // Get the Position of the Arrowhead along the length of the line.
    7.         Vector3 arrowPos = a + (dir * arrowheadDistance);
    8.  
    9.         // Get the Arrowhead Lines using the direction from earlier multiplied by a vector representing half of the full angle of the arrowhead (y)
    10.         // and -1 for going backwards instead of forwards (z), which is then multiplied by the desired length of the arrowhead lines coming from the point.
    11.  
    12.         Vector3 up = Quaternion.LookRotation(dir) * new Vector3(0f, Mathf.Sin(arrowheadAngle* Mathf.Deg2Rad), -1f) * arrowheadLength;
    13.         Vector3 down = Quaternion.LookRotation(dir) * new Vector3(0f, -Mathf.Sin(arrowheadAngle* Mathf.Deg2Rad), -1f) * arrowheadLength;
    14.  
    15.         // Draw the line from A to B
    16.         Gizmos.DrawLine(a, b);
    17.  
    18.         // Draw the rays representing the arrowhead.
    19.         Gizmos.DrawRay(arrowPos, up);
    20.         Gizmos.DrawRay(arrowPos, down);
    21.     }

    3D Gizmo Arrow Method with Connected Ends

    Code (CSharp):
    1.     private void DrawArrow(Vector3 a, Vector3 b, float arrowheadAngle, float arrowheadDistance, float arrowheadLength)
    2.     {
    3.         // Get the Direction of the Vector
    4.         Vector3 dir = b - a;
    5.  
    6.         // Get the Position of the Arrowhead along the length of the line.
    7.         Vector3 arrowPos = a + (dir * arrowheadDistance);
    8.  
    9.         // Get the Arrowhead Lines using the direction from earlier multiplied by a vector representing half of the full angle of the arrowhead (y)
    10.         // and -1 for going backwards instead of forwards (z), which is then multiplied by the desired length of the arrowhead lines coming from the point.
    11.  
    12.         Vector3 up = Quaternion.LookRotation(dir) * new Vector3(0f, Mathf.Sin(arrowheadAngle* Mathf.Deg2Rad), -1f) * arrowheadLength;
    13.         Vector3 down = Quaternion.LookRotation(dir) * new Vector3(0f, -Mathf.Sin(arrowheadAngle* Mathf.Deg2Rad), -1f) * arrowheadLength;
    14.         Vector3 left= Quaternion.LookRotation(dir) * new Vector3(Mathf.Sin(arrowheadAngle* Mathf.Deg2Rad), 0f, -1f) * arrowheadLength;
    15.         Vector3 right = Quaternion.LookRotation(dir) * new Vector3(-Mathf.Sin(arrowheadAngle* Mathf.Deg2Rad), 0f, -1f) * arrowheadLength;
    16.  
    17.         // Get the End Locations of all points for connecting arrowhead lines.
    18.         Vector3 upPos = arrowPos + up;
    19.         Vector3 downPos = arrowPos + down;
    20.         Vector3 leftPos = arrowPos + left;
    21.         Vector3 rightPos = arrowPos + right;
    22.  
    23.         // Draw the line from A to B
    24.         Gizmos.DrawLine(a, b);
    25.  
    26.         // Draw the rays representing the arrowhead.
    27.         Gizmos.DrawRay(arrowPos, up);
    28.         Gizmos.DrawRay(arrowPos, down);
    29.         Gizmos.DrawRay(arrowPos, left);
    30.         Gizmos.DrawRay(arrowPos, right);
    31.  
    32.         // Draw Connections between rays representing the arrowhead
    33.         Gizmos.DrawLine(upPos, leftPos);
    34.         Gizmos.DrawLine(leftPos, downPos);
    35.         Gizmos.DrawLine(downPos, rightPos);
    36.         Gizmos.DrawLine(rightPos, upPos);
    37.  
    38.     }


    upload_2022-6-2_21-46-21.png upload_2022-6-2_22-2-8.png
    Result of 2D Arrow (Left) | Result of 3D Arrow (Right)

    Revised Notes:

    Some of these are just if you're using either/or function and want to DIY things yourself.
    • Quaternions.Euler() is not a vital part of the method. The multiplication is used to add rotation to the end direction via quaternions. Add it after Quaternion.LookRotation() and before multiplying the new Vector3 to apply a custom rotation. Add rotation to the Z axis in this case to rotate the arrow points around the line (which preserves the direction it's facing). Rotating across the X and Y axes result in changing the direction of the arrow accordingly
    • Because there is no benefit to Quaternions.Euler() for simple arrows, this can be skipped entirely. Same with doing Mathf.Sin(arrowheadAngle* Mathf.Rad2Deg). If you want to skip this for quicker drawing, replace Mathf.Sin(arrowheadAngle * Mathf.Rad2Deg) with a value between 0f and 1f of your choice.
    • Multiplying the result by arrowheadLength can be skipped and put at a fixed value between 0f and 1f. This is just the point along the total length of the line to draw the arrowhead at.
    • To get an arrow along xz instead of xy, switch the x and y values within [ new Vector3(x, y, z) ] on line 12 and 13.
    • To get a 4-point arrow, use xz and xy variants of the 2D arrowhead simultaneously. Then call DrawRay for all four arrowhead lines.
    • To connect the lines, store the value of ArrowPos + up/down/left/right (point from direction) and draw lines connecting between each point using DrawLine(startPosition, endPosition).
    If you see any errors feel free to correct them or tell me about them. I'm still learning more about this stuff and tried to do this alone for months without knowledge of quaternions. Everything with the maths is heavily watered down and may not be accurate. I just want to provide a clearer explanation of what's going on for those who don't particularly see what's happening or why it's happening. Something I wish I had when I started the trip of learning about all the maths used here 2-3 days ago (and I'm glad I have).

    Post Original Date: June 1st, 2022 - 00:21 AM (GMT)
    Revision Date: June 2nd, 2022 - 22:05 PM (GMT)
    Revision 2 Date: November 8th, 2022 - 12:20 PM (GMT) - Removed a repeated "Magic Number" with a better solution found in university.
     
    Last edited: Nov 8, 2022
  20. onetimepad

    onetimepad

    Joined:
    Dec 30, 2021
    Posts:
    1
    Simple 2D.
    Code (CSharp):
    1.     Vector2 arrowPos;
    2.     Vector2 arrowDirection;
    3.     Vector3 angleVectorUp=new Vector3(0f, 0.40f,-1f)*0.2f/*length*/;
    4.     Vector3 angleVectorDown=new Vector3(0f, -0.40f,-1f)*0.2f/*length*/;
    5.     Vector2 upTmp;
    6.     Vector2 downTmp;
    7.     private void DrawArrow(Vector2 startPos, Vector2 endPos)
    8.     {
    9.         arrowDirection=endPos - startPos;
    10.         arrowPos = startPos + (arrowDirection*0.9f/*position along line*/);
    11.  
    12.         upTmp = Quaternion.LookRotation(arrowDirection) * angleVectorUp ;
    13.         downTmp = Quaternion.LookRotation(arrowDirection) * angleVectorDown;
    14.  
    15.         Gizmos.DrawLine(startPos, endPos);
    16.         Gizmos.DrawRay(arrowPos, upTmp);
    17.         Gizmos.DrawRay(arrowPos, downTmp);
    18.     }
    19.  
    Bez tytułu.png
    Usage:
    Code (CSharp):
    1.  private void OnDrawGizmos() {
    2. DrawArrow(startPos,endPos);
    3. }
    Thanks to Neopolitans.
     

    Attached Files:

    Neopolitans likes this.