Search Unity

[SOLVED] Handles.DoPositionHandle: Associate With GameObject Transform ?

Discussion in 'Immediate Mode GUI (IMGUI)' started by FuguFirecracker, Dec 30, 2016.

  1. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    419
    How do I associate a Handles.DoPositionHandle with a GameObject Transform such that the DoPositionHandle will appear at the GameObject's position and the inspector field will read 0:0:0 ?

    Currently I have only been able to figure out how to Draw the Handle at WorldSpace 0:0:0
    In the following image, the cube is at WorldSpace 1:0:1. You'll note the Handles at 0:0:0
    handles.png

    I am able to calculate the actual the offset position, but am unsure how to reflect this in the inspector, as any calculations I make in OnGUI have compounding results... That is, the Handles quickly fly off screen.

    What I want to be able to do is:

    Draw the Handles starting at the Cube'sTransform Position and reflect a position of 0:0:0 in the inspector...
    As I move the handles, the Position field should update to reflect the distance from the Cube.
    Conversely, As I change the inspector values, the the handles should move in relation to the Cube

    Can someone help correct my code?
    Thanks
    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3.  
    4. public class Mover : EditorWindow
    5. {
    6.     private GameObject _gameObject;
    7.     private Vector3 _handleVector;
    8.     private Vector3 _postionVector;
    9.     private Vector3 _distanceVector;
    10.  
    11.     [MenuItem("Tools/Mover")]
    12.     public static void OpenWindow()
    13.     {
    14.         var window = GetWindow<Mover>();
    15.         window.titleContent = new GUIContent("Mover");
    16.     }
    17.  
    18.     protected void OnEnable()
    19.     {
    20.         SceneView.onSceneGUIDelegate += OnSceneGUI;
    21.     }
    22.  
    23.     protected void OnDisable()
    24.     {
    25.         SceneView.onSceneGUIDelegate -= OnSceneGUI;
    26.     }
    27.  
    28.     protected void OnGUI()
    29.     {
    30.         EditorGUILayout.BeginVertical();
    31.         _gameObject = (GameObject)EditorGUILayout.ObjectField("Game Object", _gameObject, typeof(GameObject), true);
    32.         _postionVector = EditorGUILayout.Vector3Field("Position", _postionVector);
    33.         _distanceVector = EditorGUILayout.Vector3Field("Distance to Game Object", _distanceVector);
    34.         EditorGUILayout.EndVertical();
    35.     }
    36.  
    37.     protected void OnInspectorUpdate()
    38.     {
    39.         if (SceneView.lastActiveSceneView != null)
    40.         {
    41.             SceneView.lastActiveSceneView.Repaint();
    42.         }
    43.  
    44.         _handleVector = _postionVector;
    45.         _distanceVector = GetDistanceVector(_gameObject.transform.position, _handleVector);
    46.  
    47.  
    48.     }
    49.  
    50.     protected void OnSceneGUI(SceneView sceneview)
    51.     {
    52.  
    53.         if (_gameObject)
    54.         {
    55.             EditorGUI.BeginChangeCheck();
    56.             _handleVector = Handles.DoPositionHandle(_handleVector, Quaternion.identity);
    57.  
    58.  
    59.             if (EditorGUI.EndChangeCheck())
    60.             {
    61.                 _postionVector = _handleVector;
    62.                 _distanceVector = GetDistanceVector(_gameObject.transform.position, _handleVector);
    63.             }
    64.         }
    65.  
    66.         Repaint();
    67.  
    68.     }
    69.  
    70.     private Vector3 GetDistanceVector(Vector3 v1, Vector3 v2)
    71.     {
    72.         return new Vector3(Mathf.Abs(v1.x - v2.x), Mathf.Abs(v1.y - v2.y), Mathf.Abs(v1.z - v2.z));
    73.     }
    74.  
    75.  
    76.  
    77. }
    78.  
     
  2. Deleted User

    Deleted User

    Guest

  3. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    419
    Hey! If you know how to do this, don't be coy. Because... believe me ... I know what a "Transform" is.
    Vector math is not my problem. The lackluster documentation is.
     
  4. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    419
    Solved with a bool.

    Here's The Code if it helps anyone:
    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3.  
    4. public class Mover: EditorWindow
    5. {
    6.     private Vector3 _differenceVector;
    7.     private GameObject _gameObject;
    8.     private Vector3 _handleVector;
    9.     private bool _isSet;
    10.     private Vector3 _postionVector;
    11.  
    12.     private float _relativeX;
    13.     private float _relativeY;
    14.     private float _relativeZ;
    15.  
    16.  
    17.     [MenuItem("Tools/Mover")]
    18.     public static void OpenWindow()
    19.     {
    20.         var window = GetWindow<Mover>();
    21.         window.titleContent = new GUIContent("Mover");
    22.     }
    23.  
    24.     protected void OnEnable()
    25.     {
    26.         SceneView.onSceneGUIDelegate += OnSceneGUI;
    27.     }
    28.  
    29.     protected void OnDisable()
    30.     {
    31.         SceneView.onSceneGUIDelegate -= OnSceneGUI;
    32.     }
    33.  
    34.     protected void OnGUI()
    35.     {
    36.         EditorGUILayout.BeginVertical();
    37.         _gameObject = (GameObject)EditorGUILayout.ObjectField("Game Object", _gameObject, typeof(GameObject), true);
    38.         _postionVector = EditorGUILayout.Vector3Field("Position", _postionVector);
    39.  
    40.         if (_gameObject)
    41.         {
    42.             _differenceVector = _gameObject.transform.position * -1;
    43.         }
    44.  
    45.         EditorGUILayout.EndVertical();
    46.     }
    47.  
    48.     protected void OnInspectorUpdate()
    49.     {
    50.         if (SceneView.lastActiveSceneView != null)
    51.         {
    52.             SceneView.lastActiveSceneView.Repaint();
    53.         }
    54.  
    55.         if (DetectChange(_postionVector, new Vector3(_relativeX, _relativeY, _relativeZ)))
    56.         {
    57.             _relativeX = _postionVector.x - _differenceVector.x;
    58.             _relativeY = _postionVector.y - _differenceVector.y;
    59.             _relativeZ = _postionVector.z - _differenceVector.z;
    60.  
    61.             _handleVector = new Vector3(_relativeX, _relativeY, _relativeZ);
    62.         }
    63.  
    64.         if (!_gameObject)
    65.         {
    66.             _isSet = false;
    67.         }
    68.          
    69.     }
    70.  
    71.     protected void OnSceneGUI(SceneView sceneview)
    72.     {
    73.         if (_gameObject)
    74.         {
    75.             EditorGUI.BeginChangeCheck();
    76.             if (!_isSet)
    77.             {
    78.                 _handleVector = Handles.DoPositionHandle(_gameObject.transform.position, Quaternion.identity);
    79.                 _isSet = true;
    80.             }
    81.             else
    82.             {
    83.                 _handleVector = Handles.DoPositionHandle(_handleVector, Quaternion.identity);
    84.             }
    85.  
    86.             if (EditorGUI.EndChangeCheck())
    87.             {
    88.                 _postionVector = _handleVector + _differenceVector;
    89.                 _relativeX = _postionVector.x;
    90.                 _relativeY = _postionVector.y;
    91.                 _relativeZ = _postionVector.z;
    92.             }
    93.         }
    94.  
    95.         Repaint();
    96.     }
    97.  
    98.     private bool DetectChange(Vector3 v1, Vector3 v2)
    99.     {
    100.         return !Mathf.Approximately(v1.x, v2.x) || !Mathf.Approximately(v1.y, v2.y) || !Mathf.Approximately(v1.z, v2.z);
    101.     }
    102.  
     
    Nyarlathothep likes this.
  5. MartinTV

    MartinTV

    Joined:
    Jul 15, 2012
    Posts:
    6
    @FuguFirecracker
    Whoa Nelly!

    That is some complicated code right there. I was having the same issue and I think I have found a much better solution. I know this was asked almost a year ago but I hope you come back and see this.

    Basically when I am placing the handle, when I am calling the PositionHandle or DoPositionHandle method and I give the vector3 argument i also add the position of the object the component is on. THEN after i have called the PositionHandle method I subtract the objects position from it again!

    Code is from a thing I am working on. Too lazy to change the variable names to match yours haha, so sorry about that. Just pay attention to the line in OnSceneGUI.


    Code (CSharp):
    1.  
    2.  
    3.  
    4. [CustomEditor(typeof(AttackSequence))]
    5. public class HitBoxDrawer : Editor
    6. {
    7.     AttackSequence obj;
    8.  
    9.     private void OnEnable()
    10.     {
    11.         obj = (AttackSequence) target;
    12.     }
    13.  
    14.     public override void OnInspectorGUI()
    15.     {
    16.         DrawDefaultInspector();
    17.     }
    18.  
    19.     private void OnSceneGUI()
    20.     {
    21.         obj.hBox.centre = Handles.PositionHandle(obj.hBox.centre + obj.transform.position, Quaternion.identity) - obj.transform.position;
    22.     }
    23.  
    24.  
     
  6. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    419
    Hey! Thanks for the post... That does seem much simpler ;)
     
  7. mhgunning

    mhgunning

    Joined:
    Feb 17, 2020
    Posts:
    1
    idc if this thread is 2 years old, thank u this was exactly what i was trying to figure out!!
     
  8. tfalves

    tfalves

    Joined:
    Jun 27, 2014
    Posts:
    29
    Thank you for this! You just saved me a lot of time!
    Edit: Still relevant and efficient.