Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Joint anchor tool editor script

Discussion in 'Physics' started by neekoh, Apr 8, 2022.

  1. neekoh

    neekoh

    Joined:
    Nov 16, 2012
    Posts:
    9
    Hi,

    Here's a small editor script to create a custom EditorTool to edit joint anchors with a position gizmo. Not sure if later versions already have something like this built-in, but I'm still on 2020, and this has been sorely missed. It can save a lot of time vs. fiddling with the inspector values. Place this code in a script in Editor folder.

    The tool is available when a single gameobject with a joint is selected. There are cases it doesn't properly address (e.g. multiple joint components on a single object seems iffy). FixedJoints expose the anchor in script, but not sure if they are meant to be editable, so the tool is disabled in that case.

    JointAnchorTool.png


    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using UnityEditor.EditorTools;
    4.  
    5. /// <summary>
    6. /// Editor tool to set joint anchor with a position gizmo.
    7. /// </summary>
    8. [EditorTool("Joint Anchor Tool", typeof(Joint))]
    9. class JointAnchorTool : EditorTool
    10. {
    11.     GUIContent mIconContent;
    12.     GUIStyle mLabelStyle;
    13.  
    14.     void OnEnable()
    15.     {
    16.         mIconContent = new GUIContent()
    17.         {
    18.             image = EditorGUIUtility.FindTexture("AvatarPivot"),
    19.             text = "Joint Anchor Tool",
    20.             tooltip = "Modify joint anchor position"
    21.         };
    22.  
    23.         mLabelStyle = new GUIStyle(EditorStyles.miniBoldLabel);
    24.         mLabelStyle.contentOffset = new Vector2(10f, -25f);
    25.         mLabelStyle.normal.textColor = new Color(1f, 1f, 1f, 0.5f);
    26.     }
    27.  
    28.     public override GUIContent toolbarIcon
    29.     {
    30.         get { return mIconContent; }
    31.     }
    32.  
    33.     public override bool IsAvailable()
    34.     {
    35.         // Disable for multiple selection and FixedJoints
    36.         return Selection.objects.Length == 1 && !(target is FixedJoint);
    37.     }
    38.  
    39.     public override void OnToolGUI(EditorWindow window)
    40.     {
    41.         Joint joint = target as Joint;
    42.  
    43.         // Edit own anchor
    44.         Handles.matrix = joint.transform.localToWorldMatrix;
    45.         Handles.Label(joint.anchor, "Anchor", mLabelStyle);
    46.  
    47.         EditorGUI.BeginChangeCheck();
    48.         Vector3 pos = Handles.PositionHandle(joint.anchor, Quaternion.identity);
    49.         if (EditorGUI.EndChangeCheck())
    50.         {
    51.             Undo.RecordObject(target, "Joint Anchor Position");
    52.             joint.anchor = pos;
    53.         }
    54.  
    55.         // Edit connected anchor
    56.         if (!joint.autoConfigureConnectedAnchor && joint.connectedBody != null)
    57.         {
    58.             Handles.matrix = joint.connectedBody.transform.localToWorldMatrix;
    59.             Handles.Label(joint.connectedAnchor, "Connected Anchor", mLabelStyle);
    60.  
    61.             EditorGUI.BeginChangeCheck();
    62.             pos = Handles.PositionHandle(joint.connectedAnchor, Quaternion.identity);
    63.             if (EditorGUI.EndChangeCheck())
    64.             {
    65.                 Undo.RecordObject(target, "Joint Connected Anchor Position");
    66.                 joint.connectedAnchor = pos;
    67.             }
    68.         }
    69.     }
    70. }
    71.  
     
    Last edited: Apr 8, 2022
    arfish and mgear like this.
  2. Mariusz-Born7

    Mariusz-Born7

    Joined:
    Sep 4, 2015
    Posts:
    40
    You can easily edit multiple joint components on a single object or even on all selected objects by using targets instead of target and do everything in a loop.

    Code (CSharp):
    1. public override void OnToolGUI(EditorWindow window)
    2. {
    3.     foreach(Object o in targets)
    4.         {
    5.         Joint joint = o as Joint;
    6.         //...
    7.     }
    8. }