Search Unity

Draw Gizmos within ComponentSystems?

Discussion in 'Entity Component System' started by Deadcow_, Jul 3, 2018.

  1. Deadcow_

    Deadcow_

    Joined:
    Mar 13, 2014
    Posts:
    135
    Is there a way to draw gizmos?
     
  2. Rennan24

    Rennan24

    Joined:
    Jul 13, 2014
    Posts:
    38
    If you are using the Hybrid way with ComponentDataWrappers then you can use the DrawGizmos Attribute.
    But for the Pure way I'm not sure if you are able to use Gizmos at all... o_O

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3.  
    4. public class PositionWrapper : ComponentDataWrapper<PositionData> {}
    5.  
    6. [System.Serializable]
    7. public struct PositionData : IComponentData
    8. {
    9.     public Vector2 Position;
    10. }
    11.  
    12. public static class GizmoDrawers
    13. {
    14.     [DrawGizmo(GizmoType.Active | GizmoType.NotInSelectionHierarchy)]
    15.     public static void DrawGizmos(PositionWrapper wrapper, GizmoType gizmoType)
    16.     {
    17.         Gizmos.DrawWireSphere(wrapper.Value.Position, 5);
    18.     }
    19. }
     
    Mikael-H likes this.
  3. rigidbuddy

    rigidbuddy

    Joined:
    Feb 25, 2014
    Posts:
    39
    I simply wrote MonoBehaviour which invokes two events DrawGizmos, DrawGizmosSelected (in corresponding unity "magic methods") which I could use to subscribe callbacks from non-monobehaviours.

    You could also use ConcurrentQueue<Action>, dequeue & invoke them in that monobehaviours for one-shot actions.

    Or even pass IEnumerator to ConcurrentList and MoveNext them on each gizmo tick if you want coroutine-like jobs
     
  4. Deadcow_

    Deadcow_

    Joined:
    Mar 13, 2014
    Posts:
    135
    I don't quite get the idea, can you please share the source example?

    I made this
    Code (CSharp):
    1. public class MyGizmoHandler : MonoBehaviour
    2.     {
    3.         public Action DrawGizmos;
    4.         public Action DrawGizmosSelected;
    5.  
    6.         private void OnDrawGizmos()
    7.         {
    8.             DrawGizmos?.Invoke();
    9.         }
    10.  
    11.         private void OnDrawGizmosSelected()
    12.         {
    13.             DrawGizmosSelected?.Invoke();
    14.         }
    15.     }
    And my utility class for gizmos:
    Code (CSharp):
    1. public static class MyGizmo
    2. {
    3.     // some other helper methods here
    4.  
    5.     public static void OnDrawGizmos(Action action)
    6.     {
    7.         Handler.DrawGizmos += action;
    8.     }
    9.  
    10.     private static MyGizmoHandler Handler => _handler != null ? _handler : (_handler = CreateHandler());
    11.     private static MyGizmoHandler _handler;
    12.  
    13.     private static MyGizmoHandler CreateHandler()
    14.     {
    15.         var go = new GameObject("Gizmo Handler");
    16.         go.hideFlags = HideFlags.DontSave;
    17.  
    18.         return go.AddComponent<MyGizmoHandler>();
    19.     }
    20.    
    21. }
    And usage in ComponentSystem
    Code (CSharp):
    1.  
    2.  
    3. protected override void OnStartRunning()
    4.     {
    5.         MyGizmo.OnDrawGizmos(DrawGizmos);
    6.     }
    7.  
    8.     private void DrawGizmos()
    9.     {
    10.         if (_follow.Length == 0) return;
    11.         Gizmos.DrawCube(_follow.Transform[0].position, Vector3.one * 2);
    12.     }
    This called only in playmode obviously, I don't get the idea of ConcurrentQueue and one-shot actions :oops: thanks
     
    mr-gmg and Deleted User like this.
  5. rigidbuddy

    rigidbuddy

    Joined:
    Feb 25, 2014
    Posts:
    39
    1) Actually you could instantiate MyGizmoHandler in edit mode. It won't modify your active scene with hideflags = HideAndDontSave

    2) Not sure of the naming (one-shot action) but I mean the action that executes only once

    3) Here's an example of ConcurrentQueue - it's simply thread-safe equivalent of Queue:

    Code (CSharp):
    1.     public class GizmoPlayer : MonoBehaviour
    2.     {
    3.         private MyGizmo _holder;
    4.  
    5.         public void Init(MyGizmo g)
    6.         {
    7.             _holder = g;
    8.         }
    9.        
    10.         private void OnDrawGizmos()
    11.         {
    12.             while (_holder.OnGizmo.Count > 0)
    13.             {
    14.                 Action a;
    15.                 _holder.OnGizmo.TryDequeue(out a);
    16.                 a.Invoke();
    17.             }
    18.         }
    19.     }
    20.    
    21.     public class MyGizmo
    22.     {
    23.         internal ConcurrentQueue<Action> OnGizmo = new ConcurrentQueue<Action>();
    24.        
    25.         public void GizmoOneFrame(Action oneTimeAction)
    26.         {
    27.             OnGizmo.Enqueue(oneTimeAction);
    28.         }
    29.     }
    30.    
     
    Mikael-H likes this.