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

Drawing Capsule gizmo ?

Discussion in 'Editor & General Support' started by Vagabond_, Sep 13, 2015.

  1. Vagabond_

    Vagabond_

    Joined:
    Aug 26, 2014
    Posts:
    1,145
    Does anybody know a way of drawing capsule gizmo in editor?

    There are many shapes in the Gizmos class but no capsule. I assume there is a way while the Capsule primitive and the standard Capsule collider do it.
     
  2. Vagabond_

    Vagabond_

    Joined:
    Aug 26, 2014
    Posts:
    1,145
    Anyone ?
     
  3. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    926
  4. Vagabond_

    Vagabond_

    Joined:
    Aug 26, 2014
    Posts:
    1,145
    This is good enough. Thanks a ton.
     
  5. Shushustorm

    Shushustorm

    Joined:
    Jan 6, 2014
    Posts:
    1,084
    When I go into the scene or game tab, I can check "Capsule collider" in the gizmos menu.
    Isn't that what you are asking for?
     
  6. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    926
    That only enables unitys drawing of the capsule of existing colliders in your scene.
     
  7. Vagabond_

    Vagabond_

    Joined:
    Aug 26, 2014
    Posts:
    1,145
    It seems the only way to draw a custom capsule is to draw different elements in combination - "lines", "circles" and "arcs", which is achievable.
     
  8. Shushustorm

    Shushustorm

    Joined:
    Jan 6, 2014
    Posts:
    1,084
    Alright, I guess I misunderstood the question!
     
  9. Orr10c

    Orr10c

    Joined:
    Sep 11, 2016
    Posts:
    45
  10. toomasio

    toomasio

    Joined:
    Nov 19, 2013
    Posts:
    195
    Code (CSharp):
    1.  
    2. public static void DrawWireCapsule(Vector3 _pos, Quaternion _rot, float _radius, float _height, Color _color = default(Color))
    3.     {
    4.         if (_color != default(Color))
    5.             Handles.color = _color;
    6.         Matrix4x4 angleMatrix = Matrix4x4.TRS(_pos, _rot, Handles.matrix.lossyScale);
    7.         using (new Handles.DrawingScope(angleMatrix))
    8.         {
    9.             var pointOffset = (_height - (_radius * 2)) / 2;
    10.  
    11.             //draw sideways
    12.             Handles.DrawWireArc(Vector3.up * pointOffset, Vector3.left, Vector3.back, -180, _radius);
    13.             Handles.DrawLine(new Vector3(0, pointOffset, -_radius), new Vector3(0, -pointOffset, -_radius));
    14.             Handles.DrawLine(new Vector3(0, pointOffset, _radius), new Vector3(0, -pointOffset, _radius));
    15.             Handles.DrawWireArc(Vector3.down * pointOffset, Vector3.left, Vector3.back, 180, _radius);
    16.             //draw frontways
    17.             Handles.DrawWireArc(Vector3.up * pointOffset, Vector3.back, Vector3.left, 180, _radius);
    18.             Handles.DrawLine(new Vector3(-_radius, pointOffset, 0), new Vector3(-_radius, -pointOffset, 0));
    19.             Handles.DrawLine(new Vector3(_radius, pointOffset, 0), new Vector3(_radius, -pointOffset, 0));
    20.             Handles.DrawWireArc(Vector3.down * pointOffset, Vector3.back, Vector3.left, -180, _radius);
    21.             //draw center
    22.             Handles.DrawWireDisc(Vector3.up * pointOffset, Vector3.up, _radius);
    23.             Handles.DrawWireDisc(Vector3.down * pointOffset, Vector3.up, _radius);
    24.  
    25.         }
    26.     }
    27.  
     
    Last edited: Jan 14, 2019
    fdz_, ElasticSea, dev_reimu and 7 others like this.
  11. Deleted User

    Deleted User

    Guest

    Thanks, nice snippet!

    Here's my version between two points
    Code (CSharp):
    1.     public static void DrawWireCapsule(Vector3 _pos, Vector3 _pos2, float _radius, float _height, Color _color = default)
    2.     {
    3.         if (_color != default) Handles.color = _color;
    4.  
    5.         var forward = _pos2 - _pos;
    6.         var _rot = Quaternion.LookRotation(forward);
    7.         var pointOffset = _radius/2f;
    8.         var length = forward.magnitude;
    9.         var center2 = new Vector3(0f,0,length);
    10.        
    11.         Matrix4x4 angleMatrix = Matrix4x4.TRS(_pos, _rot, Handles.matrix.lossyScale);
    12.        
    13.         using (new Handles.DrawingScope(angleMatrix))
    14.         {
    15.             Handles.DrawWireDisc(Vector3.zero, Vector3.forward, _radius);
    16.             Handles.DrawWireArc(Vector3.zero, Vector3.up, Vector3.left * pointOffset, -180f, _radius);
    17.             Handles.DrawWireArc(Vector3.zero, Vector3.left, Vector3.down * pointOffset, -180f, _radius);
    18.             Handles.DrawWireDisc(center2, Vector3.forward, _radius);
    19.             Handles.DrawWireArc(center2, Vector3.up, Vector3.right * pointOffset, -180f, _radius);
    20.             Handles.DrawWireArc(center2, Vector3.left, Vector3.up * pointOffset, -180f, _radius);
    21.            
    22.             DrawLine(_radius,0f,length);
    23.             DrawLine(-_radius,0f,length);
    24.             DrawLine(0f,_radius,length);
    25.             DrawLine(0f,-_radius,length);
    26.         }
    27.     }
    28.  
    29.     private static void DrawLine(float arg1,float arg2,float forward)
    30.     {
    31.         Handles.DrawLine(new Vector3(arg1, arg2, 0f), new Vector3(arg1, arg2, forward));
    32.     }
     
  12. Wasserwecken

    Wasserwecken

    Joined:
    Oct 9, 2017
    Posts:
    6
    Thanks for the base, heres my version for drawing the capsule with two centers and radius, like CapsuleCast() / CheckCapsule() /

    Code (CSharp):
    1.     /// <summary>
    2.     ///
    3.     /// </summary>
    4.     private static void DrawWireCapsule(Matrix4x4 space, Vector3 upper, Vector3 lower, float radius)
    5.     {
    6.         using (new Handles.DrawingScope(space))
    7.         {
    8.             var offsetCenter = Vector3.Distance(upper, lower);
    9.             var offsetX = new Vector3(radius, 0f, 0f);
    10.             var offsetZ = new Vector3(0f, 0f, radius);
    11.  
    12.             //draw frontways
    13.             Handles.DrawWireArc(upper, Vector3.back, Vector3.left, 180, radius);
    14.             Handles.DrawLine(lower + offsetX, upper + offsetX);
    15.             Handles.DrawLine(lower - offsetX, upper - offsetX);
    16.             Handles.DrawWireArc(lower, Vector3.back, Vector3.left, -180, radius);
    17.             //draw sideways
    18.             Handles.DrawWireArc(upper, Vector3.left, Vector3.back, -180, radius);
    19.             Handles.DrawLine(lower + offsetZ, upper + offsetZ);
    20.             Handles.DrawLine(lower - offsetZ, upper - offsetZ);
    21.             Handles.DrawWireArc(lower, Vector3.left, Vector3.back, 180, radius);
    22.             //draw center
    23.             Handles.DrawWireDisc(upper, Vector3.up, radius);
    24.             Handles.DrawWireDisc(lower, Vector3.up, radius);
    25.         }
    26.     }
     
    dshimmyo likes this.
  13. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,108
    Maybe I missed something, but your version could not be rotated by using
    Gizmos.matrix = transform.localToWorldMatrix;

    so I made my custom version working exactly like other wire gizmos (except zTest)
    Code (CSharp):
    1.  
    2.     public static void DrawWireCapsule(Vector3 p1, Vector3 p2, float radius)
    3.     {
    4.         #if UNITY_EDITOR
    5.         // Special case when both points are in the same position
    6.         if (p1 == p2)
    7.         {
    8.             // DrawWireSphere works only in gizmo methods
    9.             Gizmos.DrawWireSphere(p1, radius);
    10.             return;
    11.         }
    12.         using (new UnityEditor.Handles.DrawingScope(Gizmos.color, Gizmos.matrix))
    13.         {
    14.             Quaternion p1Rotation = Quaternion.LookRotation(p1 - p2);
    15.             Quaternion p2Rotation = Quaternion.LookRotation(p2 - p1);
    16.             // Check if capsule direction is collinear to Vector.up
    17.             float c = Vector3.Dot((p1 - p2).normalized, Vector3.up);
    18.             if (c == 1f || c == -1f)
    19.             {
    20.                 // Fix rotation
    21.                 p2Rotation = Quaternion.Euler(p2Rotation.eulerAngles.x, p2Rotation.eulerAngles.y + 180f, p2Rotation.eulerAngles.z);
    22.             }
    23.             // First side
    24.             UnityEditor.Handles.DrawWireArc(p1, p1Rotation * Vector3.left,  p1Rotation * Vector3.down, 180f, radius);
    25.             UnityEditor.Handles.DrawWireArc(p1, p1Rotation * Vector3.up,  p1Rotation * Vector3.left, 180f, radius);
    26.             UnityEditor.Handles.DrawWireDisc(p1, (p2 - p1).normalized, radius);
    27.             // Second side
    28.             UnityEditor.Handles.DrawWireArc(p2, p2Rotation * Vector3.left,  p2Rotation * Vector3.down, 180f, radius);
    29.             UnityEditor.Handles.DrawWireArc(p2, p2Rotation * Vector3.up,  p2Rotation * Vector3.left, 180f, radius);
    30.             UnityEditor.Handles.DrawWireDisc(p2, (p1 - p2).normalized, radius);
    31.             // Lines
    32.             UnityEditor.Handles.DrawLine(p1 + p1Rotation * Vector3.down * radius, p2 + p2Rotation * Vector3.down * radius);
    33.             UnityEditor.Handles.DrawLine(p1 + p1Rotation * Vector3.left * radius, p2 + p2Rotation * Vector3.right * radius);
    34.             UnityEditor.Handles.DrawLine(p1 + p1Rotation * Vector3.up * radius, p2 + p2Rotation * Vector3.up * radius);
    35.             UnityEditor.Handles.DrawLine(p1 + p1Rotation * Vector3.right * radius, p2 + p2Rotation * Vector3.left * radius);
    36.         }
    37.         #endif
    38.     }

    EDIT:
    If you want to draw capsule based on CapsuleCollider, then you can do this:
    Code (CSharp):
    1. // collider is CapsuleCollider
    2. Gizmos.matrix = collider.transform.localToWorldMatrix;
    3.  
    4. Vector3 offset = Vector3.zero;
    5. offset[collider.direction] = collider.height * 0.5f - collider.radius;
    6. DrawWireCapsule(collider.center + offset, collider.center - offset, collider.radius);
     
    Last edited: Sep 25, 2022
  14. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    Works great! Until...

    upload_2022-10-19_22-34-42.png

    Changing the rotation on the Y or Z axis very slightly corrects it.