Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Set Physics 2D Gizmos from script

Discussion in '2D' started by Baste, May 23, 2023.

  1. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,294
    Is there a way to set the value of this menu from code

    upload_2023-5-23_15-31-12.png

    ?

    We had a little debug window in Teslagrad 2 to quickly turn on and off gizmos for 2D colliders in the scene, and it was amazing for understanding issues. Here's a little preview in action:

    Unity_eNeJPhtQMP.gif

    The problem is, I never figured out how to edit the collider gizmos from script, so all of those lines are custom implemented [DrawGizmos] functions for every single Collider2D type, which has to do all of the annoying work of respecting transform rotations and scales and stuff and such.
    So it's probably still got bugs where the gizmos are not entirely correct, and I probably perform a lot worse than what builtin gizmos does due to no batching and method call overhead and all of that sadness.

    I was looking and transferring the code to a new project, but I would love to just be able to just set the values for Unity's Gizmos stuff instead. But it seems like the best candidate, Physics2D.alwaysShowColliders is deprecated. Is there some API method I'm missing, or can I set a secret value in EditorPrefs like with some other Unity settings?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    That does seem like a pretty spiffy feature to have, especially for making 2D colliders in otherwise-3D setups.

    Does wiggling that value from code have the desired effect? If so, use it for now! :)

    It is most likely reachable via reflection.
     
  3. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,326
    Yes, they were removed because they existed in the runtime (previous mistake) and there was a lot of refactoring that happened during that release.

    The colours are stored as EditorPrefs (see attached script to directly access them) but the gizmo options are now Editor only project settings as a flags enum. You'll find that enum property in the "Physics2DSettings.asset" named "m_GizmoOptions".

    That's a bit of a miss on my part for not exposing that option editor-only. I'll see what I can do about that.

    Sorry for the inconvenience.
     

    Attached Files:

  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,326
    So, that source file referenced above should have something like:
    Code (CSharp):
    1.         [StaticAccessor("GetPhysics2DSettings()")]
    2.         extern public static GizmoOptions gizmoOptions { get; set; }
    3.  
    4.         // Needs to match "Physics2DSettings.h"
    5.         [Flags]
    6.         public enum GizmoOptions
    7.         {
    8.             AllColliders        = 1 << 0,
    9.             CollidersOutlined   = 1 << 1,
    10.             CollidersFilled     = 1 << 2,
    11.             CollidersSleeping   = 1 << 3,
    12.             ColliderContacts    = 1 << 4,
    13.             ColliderBounds      = 1 << 5
    14.         };
    :(
     
  5. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,294
    Thanks! I'll see what I can do with that. My old solution still works (and it allows me to have more specific behaviour, like showing gizmos only for certain layers), but if I can hack something, that'd be great.

    Honestly, the best thing would be a way to tell the Gizmos system to "please draw gizmos for this specific collider with this color".
     
    MelvMay likes this.
  6. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,294
    Hey, wait, could I perhaps update my Gizmo drawer to use Collider2D.GetShapes?

    In that case I could write a generic algorithm that just draws a PhysicsShapeGroup2D, and then have a single [DrawGizmo] for Collider2D. From what I can tell from PhysicsShapeGroup2D, it has a localToWorldMatrix that I can use to transform everything to world space, so it should probably have all the data I need without having to include the transforms.
     
  7. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,326
    Yes, that would work for any collider type i.e. drawing the shape primitives. You can also read and cache the Collider2D.GetShapeHash and only call Collider2D.GetShapes (caching the PhysicsShapeGroup2D) if that changes. This is what is done for the CustomCollider2D for instance as that is a collection of shapes only.

    Be aware though that if you get world-space shape data then the shape hash won't change if the collider moves attached to a Rigidbody2D because the collider hasn't changed. Asking for local-space shapes and drawing the gizmos in the space of the Rigidbody2D is how it's done internally. If no Rigidbody2D exists (Static Collider) then local-space = world-space anyway.

    Snippet of C++ gizmo code for this:
    Code (CSharp):
    1.         // Do we have a rigidbody component?
    2.         Rigidbody2D* rigidBody = collider->GetAttachedRigidbody();
    3.         if (rigidBody != NULL)
    4.         {
    5.             // Yes, so use the transform at the rigidbody position.
    6.             const Transform& rigidbodyTransform = rigidBody->GetComponent<Transform>();
    7.             gizmoPosition = rigidbodyTransform.GetPosition();
    8.             gizmoPosition.z = colliderTransform.GetPosition().z;
    9.             gizmoRotation = PhysicsUtility2D::ZRotFromFullRot(rigidbodyTransform.GetRotation());
    10.         }
    11.         else
    12.         {
    13.             // No, so reset the gizmo position/rotation as this is pre-calculated inside the collider.
    14.             gizmoPosition.Set(0.0f, 0.0f, colliderTransform.GetPosition().z);
    15.             gizmoRotation = Quaternionf::identity();
    16.         }
    The "ZRotFromFullRot" thing isn't appropriate if you only have Z rotation and no XY rotation. In that case you can just assign the Transform rotation here.
     
    Baste likes this.
  8. aegis123321

    aegis123321

    Joined:
    Jul 5, 2015
    Posts:
    54
    Hello, I wonder if this property exposed in 2022.3 since I still didn't find it out. :(