Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    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,148
    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,148
    Anyone ?
     
  3. Flavelius

    Flavelius

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

    Vagabond_

    Joined:
    Aug 26, 2014
    Posts:
    1,148
    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:
    943
    That only enables unitys drawing of the capsule of existing colliders in your scene.
     
  7. Vagabond_

    Vagabond_

    Joined:
    Aug 26, 2014
    Posts:
    1,148
    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:
    197
    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.     }
     
    ajtwoddl0408 and dshimmyo like this.
  13. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,225
    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.