Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
8
Question by davidisak · Nov 28, 2014 at 11:24 PM · 2dcolliderdebugcirclegizmos

Draw 2d circle with Gizmos

Hi!

I'm creating a script that draws gizmos for all 2D colliders in my 2D scene. My question is: how do I draw a gizmo for a 2D circle the same way you see gizmos when selecting an object? The only function in Gizmos that I find close to this is "DrawWireSphere()" but it draws a sphere and i can only give it a position and radius and not a rotation.

Here's what I want (from a 3D perspective):
alt text

Here's what I have right now (from a 3D perspective):
alt text

So I simply just want to draw the circle in the xy-plane and have the options to rotate on any axis.

To see the Z-rotation from a 2D-perspective I will just draw lines like a cross over the circle. I can do that now aswell but it will be confusing to see all the sphere circles at the same time.

EDIT: The circle i want to draw should be for all game objects in the scene and not only targeted game objects.

SOLUTION

As suggested by buckius82 below, a solution for this is to make a monobehavior script that retrieves all CircleCollider2D's in the scene and then draw wire discs (UnityEdtior.Handles.DrawWireDisc) under the OnDrawGizmos() method.

Example:

 private void OnDrawGizmos(){
   UnityEditor.Handles.color = Color.yellow;
   CircleCollider2D[] colliders = FindObjectsOfType (typeof(CircleCollider2D)) as Collider2D[];
   foreach(CircleCollider2D collider in colliders){
     UnityEditor.Handles.DrawWireDisc(collider.transform.position ,Vector3.back, collider.radius);
   }
 }

Note that this may take some performance if there are alot of colliders in the scene.

want.png (8.5 kB)
have.png (20.5 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

6 Replies

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

Answer by buckius82 · Jan 31, 2015 at 04:47 PM

I wanted to make 2d circle in 3d to represent spread in the editor.

Look At editor.handles

 using UnityEditor;
 using UnityEngine;
 public class customclassEditor: MonoBehaviour
 {
     public float variance;    // This much variance 
     public float maxdistance; // at this distance
     
 }
         
 using UnityEditor;
 using UnityEngine;
 using System.Collections;
 
 [CustomEditor(typeof(customclass))]
 public class customclassEditor: Editor 
 {
     
     private customclass c;
         
     public void OnSceneGUI () 
     {
         c = this.target as customclass;
         Handles.color = Color.red;
         Handles.DrawWireDisc(c.transform.position +(c.transform.forward *c.Range) // position
                                       , c.transform.forward                       // normal
                                       , c.variance);                              // radius
     }
  }

i hop this can get you started

Comment
Add comment · Show 4 · 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 davidisak · Jan 31, 2015 at 08:21 PM 0
Share

@buckius82, Thanks for answer. I can see your example looks much like the one from the documentation of drawWireDisc, I have tried this but as mentioned in the comments to yashpal response, this only makes the circle of the targeted game object visible and not all game objects in the scene with a CircleCollider2D attached. I forgot to mention this in the question so I will edit the question and add that it needs to be drawn for all game objects and not only targeted game objects.

avatar image buckius82 · Jan 31, 2015 at 11:37 PM 0
Share

you ready, i wanted to be able to see all turret spread patterns on a GO. onSceneGUI only works if the OBJ is slelected. so if i had multple turrets as children of a single parent i can't see the arcs and spread. but i can using OnDrawGizmosSelected()

here is a class for you using UnityEngine; using System.Collections;

 public class CircleAroundEachGameObject : $$anonymous$$onoBehaviour
 {
 
     void OnDrawGizmosSelected()
     {
         GameObject[] objs = FindObjectsOfType(typeof(GameObject))as GameObject[];
         foreach (GameObject g in objs)
         {
             UnityEditor.Handles.color = Color.green;
             UnityEditor.Handles.DrawWireDisc(g.transform.position , g.transform.up, 2f);
         }
     }
 }

now if you attach this to a obj in the scene it will show a circle around every game object.

now lets say you want it to always show it then use OnDrawGizmos() ins$$anonymous$$d.

now i'm asu$$anonymous$$g these represent 2d coliders try

 using UnityEngine;
 using System.Collections;
 
 public class CircleAroundEachGameObject : $$anonymous$$onoBehaviour
 {
     public float radius;
     public Vector3 direction;
 
     void OnDrawGizmosSelected()
     {
         direction = Vector3.Normalize(direction);
         GameObject[] objs = FindObjectsOfType(typeof(GameObject))as GameObject[];
         foreach (GameObject g in objs)
         {
             float r = radius;
             CircleCollider2D c2d = g.GetComponent<CircleCollider2D>();
             if(c2d != null)
             {    r = c2d.radius;
                 UnityEditor.Handles.color = Color.green;
                 UnityEditor.Handles.DrawWireDisc(g.transform.position ,direction, r);
             }
         }
     }
 }
 

if you want to be able to modify the colliders using the these circles through drag and drop you'll have to use onscene gui and create the editor controls look here http://catlikecoding.com/unity/tutorials/curves-and-splines/

avatar image davidisak · Feb 01, 2015 at 02:58 AM 0
Share

@buckius82, right that solves it, I didn't think of using Handles inside the OnDrawGizmos method as it's mainly meant for drawing gizmos but this solves the problem well enough to satisfy me :p Will edit the post and add a short description for the solution for people to find it easier. cheers

avatar image Edy · Oct 04, 2017 at 11:50 PM 1
Share

The problem with using Handles inside OnDrawGizmos is that it won't compile to a binary. You have to enclose it in #if UNITY_EDITOR / #endif in order to make a build.

avatar image
5

Answer by xibanya · Dec 21, 2019 at 02:32 AM

I also wanted to draw gizmo disks. Here's the solution I came up with, which doesn't require using an editor script. You can stick it into a static utility class, then call it with transform.DrawGizmoDisk(radius: 0.5f) or whatever.

         private const float GIZMO_DISK_THICKNESS = 0.01f;

         public static void DrawGizmoDisk(this Transform t, float radius)
         {
             Matrix4x4 oldMatrix = Gizmos.matrix;
             Gizmos.color = new Color(0.2f, 0.2f, 0.2f, 0.5f); //this is gray, could be anything
             Gizmos.matrix = Matrix4x4.TRS(t.position, t.rotation, new Vector3(1, GIZMO_DISK_THICKNESS, 1));
             Gizmos.DrawSphere(Vector3.zero, radius);
             Gizmos.matrix = oldMatrix;
         }

Bit hacky (it's just a squished sphere) but good enough for visualizing a radius! example of two squished gizmos spheres in action

You can also easily modify this to draw a wire sphere instead, or both at the same time (as pictured here), but since this is a squished 3d gizmo, if you draw the wire sphere, there's no avoiding the "cross" that shows up with it. Still, it's probably the closest you can get without having to use the custom editor APIs (I consider that a plus if I am otherwise not gonna need a custom editor!)

alt text

Here's an example of drawing the squished wire sphere that takes a position as an argument rather than being an extension method of a transform.

 public static void DrawWireDisk(Vector3 position, float radius, Color color)
     {
         Color oldColor = Gizmos.color;
         Gizmos.color = color;
         Matrix4x4 oldMatrix = Gizmos.matrix;
         Gizmos.matrix = Matrix4x4.TRS(position, Quaternion.identity, new Vector3(1, GIZMO_DISK_THICKNESS, 1));
         Gizmos.DrawWireSphere(Vector3.zero, radius);
         Gizmos.matrix = oldMatrix;
         Gizmos.color = oldColor;
     }


screenhunter-4628.png (516.3 kB)
Comment
Add comment · Show 2 · 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 NeatWolf · Dec 23, 2019 at 10:02 AM 0
Share

I really love this solution! Also, it $$anonymous$$ches how to use the matrix field in a very practical way.

In particular, it makes it clear how to re-orient the facing just by changing Quaternion.identity to your favourite "up" rotation (or, the rotation of the transform)

too bad the number of subdivisions of the sphere can't be increased! :)

avatar image IC_ · Feb 15, 2020 at 04:03 AM 0
Share

This approach also works fine with Handles. APIs

avatar image
1
Wiki

Answer by yashpal · Jan 31, 2015 at 12:55 PM

@davidisak, I think you need to make your custom editor script to do this.(correct me if i am wrong.). You want to use Handles.DrawWireDisc. use Handles for more customization.

Comment
Add comment · Show 6 · 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 davidisak · Jan 31, 2015 at 01:02 PM 0
Share

@yashpal, Thanks for the answer, this sounds just like what I need. I will try it out when I get the time and verify your answer as correct if it works well!

avatar image davidisak · Jan 31, 2015 at 01:46 PM 0
Share

@yashpal, I tried it out but realized that the OnSceneGUI in my customeditor is only called when I select the game object. What I want is to draw the circles for all CircleCollider2D's in the scene without having to select them. Any idea on this?

avatar image Bunny83 · Jan 31, 2015 at 02:49 PM 0
Share

@davidisak: in this case you have two options:

  • attach a script to each collider with implements OnDrawGizmos

  • use an editorwindow and register an onsceneview callback in the SceneView class. In this case you have to draw all gizmos in that one callback

avatar image davidisak · Jan 31, 2015 at 03:19 PM 0
Share

@Bunny83, I currently have a script that retrieves all colliders in the scene and draws gizmos for them in onDrawGizmos(), however my problem is that there are no such function in Gizmos that lets you draw a simple 2d circle such as the DrawWireDisc in Handles. So now I am now wondering if I can use the Handles draw-functions for all colliders in the scene (and not only for selected objects) ins$$anonymous$$d of gizmos, as suggested by yashpal.

avatar image buckius82 · Feb 01, 2015 at 05:45 AM 0
Share

@Bunny83 yes you can

Show more comments
avatar image
1

Answer by James2Games · Nov 05, 2019 at 09:50 PM

Here's a solution using Gizmos. Only tested this so it displays in a world space canvas in the Z direction but can be adjusted in the Euler method to display on any angle.

 float corners = 11; // How many corners the circle should have
 float size = 10; // How wide the circle should be
 Vector3 origin = transform.position; // Where the circle will be drawn around
 Vector3 startRotation = transform.right * size; // Where the first point of the circle starts
 Vector3 lastPosition = origin + startRotation;
 float angle = 0;
 while (angle <= 360)
 {
     angle += 360 / corners;
     Vector3 nextPosition = origin + (Quaternion.Euler(0, 0, angle) * startRotation);
     Gizmos.DrawLine(lastPosition, nextPosition);
     Gizmos.DrawSphere(nextPosition, 1);
 
     lastPosition = nextPosition;
 }
Comment
Add comment · Show 1 · 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
0

Answer by Owen9047 · Feb 09 at 03:44 AM

I wanted a version of @James2Games solution that takes a normal and position instead of a full transform. Here's what I came up with:

 public static void DrawGizmosCircle(Vector3 pos, Vector3 normal, float radius, int numSegments)
 {
     // I think of normal as conceptually in the Y direction.  We find the
     // "forward" and "right" axes relative to normal and I think of them 
     // as the X and Z axes, though they aren't in any particular direction.
     // All that matters is that they're perpendicular to each other and on
     // the plane defined by pos and normal.
     Vector3 temp = (normal.x < normal.z) ? new Vector3(1f, 0f, 0f) : new Vector3(0f, 0f, 1f);
     Vector3 forward = Vector3.Cross(normal, temp).normalized;
     Vector3 right = Vector3.Cross(forward, normal).normalized;
 
     Vector3 prevPt = pos + (forward * radius);
     float angleStep = (Mathf.PI * 2f) / numSegments;
     for (int i = 0; i < numSegments; i++)
     {
         // Get the angle for the end of this segment.  If it's the last segment,
         // use the angle of the first point so the last segment meets up with
         // the first point exactly (regardless of floating point imprecision).
         float angle = (i == numSegments - 1) ? 0f : (i + 1) * angleStep;
 
         // Get the segment end point in local space, i.e. pretend as if the
         // normal was (0, 1, 0), forward was (0, 0, 1), right was (1, 0, 0),
         // and pos was (0, 0, 0).
         Vector3 nextPtLocal = new Vector3(Mathf.Sin(angle), 0f, Mathf.Cos(angle)) * radius;
 
         // Transform from local to world coords.  nextPtLocal's x,z are distances
         // along its axes, so we want those as the distances along our right and
         // forward axes.
         Vector3 nextPt = pos + (right * nextPtLocal.x) + (forward * nextPtLocal.z);
 
         Gizmos.DrawLine(prevPt, nextPt);
 
         prevPt = nextPt;
     }
 }

Comment
Add comment · 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
  • 1
  • 2
  • ›

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

12 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

Related Questions

How can I see my physics2d joints? 0 Answers

2D - How can I create an "inverted" circle collider? 1 Answer

Detect a collision but allow prefabs to pass through each other 2 Answers

Why does Physics2D.Capsule/Circle/BoxCast's hit point and distance not line up? 0 Answers

Cirlce Colliders 0 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