Search Unity

character joint swing and twist axes

Discussion in 'Editor & General Support' started by dmorton, Jun 14, 2009.

  1. dmorton

    dmorton

    Joined:
    Jan 14, 2009
    Posts:
    119
    I cant for the life of me figure out the gizmos for the character joint twist and swing axes.

    The documentation tells me that the orange axis is the twist axis, while the green axis is swing1. A further non-displayed axis perpendicular to both is swing2.

    My intuition tells me that the twist axis should be a line about which the object in question rotates. If its an arm, for example, the twist axis should be parallel to the length of the arm.

    In Unity 2.5, these axes are completely out of whack.

    In the attached image, I have made two objects connected by a character joint. As it stands, he hanging capsule is constrained to swinging left and right only - no twist and no swing2.

    You can see in the attached image that the orange twist-axis gizmo (centered in the cube) is pointing in a direction that seemingly has nothing to do with twist, while the green swing axis gizmo seems to be pointing down the length of the capsule, in what to my mind should be the twist axis.

    Have I completely misunderstood what these axes represent?

    Actually, these gizmos would be better represented by coloured arc/wedges showing the upper and lower limits of motion. They would be much easier to see like that, and the information represented would be more informative.
     

    Attached Files:

  2. dmorton

    dmorton

    Joined:
    Jan 14, 2009
    Posts:
    119
    So Ive started work on an editor script to enhance the character joint to display ranges of motion.

    Still trying to figure out what the axes actually represent.

    If anyone could take a moment to explain their understanding of them, it would be greatly appreciated.
     

    Attached Files:

  3. dmorton

    dmorton

    Joined:
    Jan 14, 2009
    Posts:
    119
    Ok, here is my first stab at some code for displaying the ranges of motion for a character joint. I think I have figured out what the axes represent.

    They represent not the axes about which that range of motion turns, but rather the current direction of the rotation about the relevant axis.

    To use the script(s) you need to drop the EnhanceCharacterJointEditor.cs into your Assets/Editor folder, while dropping the EnhanceCharacterJoint onto GameObjects with CharacterJoints you want to enhance with display of their ranges of motion.

    Orange is twist, Green is swing1 and Blue is swing2.

    Code (csharp):
    1.  
    2. // file: EnhanceCharacterJoint.cs
    3. [RequireComponent (typeof (CharacterJoint))]
    4. public class EnhanceCharacterJoint : MonoBehaviour {
    5. }
    6.  
    7. // file: EnhanceCharacterJointEditor.cs
    8. [CustomEditor(typeof(EnhanceCharacterJoint))]
    9. class EnhanceCharacterJointEditor : Editor
    10. {
    11.     void OnSceneGUI () {
    12.        
    13.         //Debug.Log(this.target.GetType());
    14.         EnhanceCharacterJoint script = (EnhanceCharacterJoint) this.target;
    15.         if (script != null)
    16.         {
    17.             CharacterJoint joint = (CharacterJoint) script.gameObject.GetComponent(typeof(CharacterJoint));
    18.            
    19.             Vector3 twistAxis = joint.transform.TransformDirection(joint.axis).normalized;
    20.             Vector3 swing1Axis = joint.transform.TransformDirection(joint.swingAxis).normalized;
    21.             Vector3 swing2Axis = Vector3.Cross(twistAxis, swing1Axis);         
    22.            
    23.             float size = HandleUtility.GetHandleSize(joint.transform.position);
    24.            
    25.             Handles.color = new Color(1,0.5f,0) ; // orange == twist, direction = swing1, rotates about twist axis
    26.             Handles.DrawWireArc(joint.transform.position, twistAxis, swing1Axis, joint.highTwistLimit.limit, size);
    27.             Handles.DrawWireArc(joint.transform.position, twistAxis, swing1Axis, joint.lowTwistLimit.limit, size);
    28.             Handles.DrawLine(joint.transform.position, joint.transform.position + Quaternion.AngleAxis(joint.highTwistLimit.limit, twistAxis) * swing1Axis * size);
    29.             Handles.DrawLine(joint.transform.position, joint.transform.position + Quaternion.AngleAxis(joint.lowTwistLimit.limit, twistAxis) * swing1Axis * size);
    30.            
    31.             Handles.color = new Color(0,0.3f,0) ; // green=swing1, direction=twistAxis rotates about swing1Axis
    32.             Handles.DrawWireArc(joint.transform.position, swing1Axis, twistAxis, joint.swing1Limit.limit, size);
    33.             Handles.DrawWireArc(joint.transform.position, swing1Axis, twistAxis, -joint.swing1Limit.limit, size);          
    34.             Handles.DrawLine(joint.transform.position, joint.transform.position + Quaternion.AngleAxis(joint.swing1Limit.limit, swing1Axis) * twistAxis * size);
    35.             Handles.DrawLine(joint.transform.position, joint.transform.position + Quaternion.AngleAxis(-joint.swing1Limit.limit, swing1Axis) * twistAxis * size);
    36.            
    37.             Handles.color = new Color(0,0,0.5f); // blue=swing2, direction=twistAxis, rotates about swing2 axis
    38.             Handles.DrawWireArc(joint.transform.position, swing2Axis, twistAxis, joint.swing2Limit.limit, size);
    39.             Handles.DrawWireArc(joint.transform.position, swing2Axis, twistAxis, -joint.swing2Limit.limit, size);          
    40.             Handles.DrawLine(joint.transform.position, joint.transform.position + Quaternion.AngleAxis(joint.swing2Limit.limit, swing2Axis) * twistAxis * size);
    41.             Handles.DrawLine(joint.transform.position, joint.transform.position + Quaternion.AngleAxis(-joint.swing2Limit.limit, swing2Axis) * twistAxis * size);              
    42.         }
    43.     }
    44. }
     

    Attached Files:

  4. Lucas Meijer_old

    Lucas Meijer_old

    Joined:
    Apr 5, 2008
    Posts:
    436
    Hey.

    Not much help here, but a longshot: whenever I'm surprised by how unity's gizmo's behave, sometimes it starts behaving like I expect it to if I mess with their settings. (center/pivot and local/global in the top of the unity interface)

    Good luck, Lucas
     
  5. Minassian

    Minassian

    Joined:
    Nov 22, 2010
    Posts:
    40
    Please add the includes in each file (UnityEngine for EnhacedCharacterJoint.cs and UnityEngine,UnityEditor for EnhacedCharacterJoint Editor.cs).
    It can be a time waster for people that never touched C#.

    Thanks for the script, definitevelly a geat resource to work with CharacterJoints !
     
  6. Emericanized

    Emericanized

    Joined:
    Apr 30, 2010
    Posts:
    23
    You, sir, are my hero. and I hope beyond hope that Unity will tweak their displays on this stuff by default!

    Edit: You should really submit this to the wiki. That way a lot more people will be able to find your script!

    (I found it by chance through a google search: "how to use character joint axis transforms")
     
    Last edited: Feb 15, 2012
  7. masterprompt

    masterprompt

    Joined:
    Jan 6, 2009
    Posts:
    114
    I think this is right.... not sure...

    Code (csharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using System;
    6.  
    7. [CustomEditor(typeof(EnhanceCharacterJoint))]
    8. public class EnhanceCharacterJointInspector : Editor
    9. {
    10.  
    11.     #region Properties
    12.     private EnhanceCharacterJoint targetScript = null;
    13.     private static Color twistColor = new Color(255f / 255f, 187f / 255f, 0, 0.5f);
    14.     private static Color swing1Color = new Color(31f / 255f, 82f / 255f, 0, 0.5f);
    15.     private static Color swing2Color = new Color(0, 34f / 255f, 82f / 255f, 0.5f);
    16.  
    17.     #endregion
    18.  
    19.     #region Editor
    20.     public override void OnInspectorGUI()
    21.     {
    22.         targetScript = (EnhanceCharacterJoint)target;
    23.         twistColor = EditorGUILayout.ColorField("Twist Color", twistColor);
    24.         swing1Color = EditorGUILayout.ColorField("Swing 1 Color", swing1Color);
    25.         swing2Color = EditorGUILayout.ColorField("Swing 2 Color", swing2Color);
    26.         EditorUtility.SetDirty(targetScript);
    27.         Repaint();
    28.        
    29.     }
    30.  
    31.     public void OnSceneGUI()
    32.     {
    33.         targetScript = (EnhanceCharacterJoint)target;
    34.  
    35.         Color blackColor = Color.black;
    36.  
    37.  
    38.         CharacterJoint joint = targetScript.GetComponent<CharacterJoint>();
    39.  
    40.         Vector3 jointCenter = joint.transform.TransformPoint(joint.anchor);
    41.         Vector3 twistAxis = joint.transform.TransformDirection(joint.axis).normalized;
    42.        
    43.         Vector3 forwardAxis = joint.transform.TransformDirection(Vector3.forward);
    44.  
    45.         //  90 to the twist axis
    46.         Vector3 twist90 = Vector3.Cross(twistAxis, forwardAxis);
    47.  
    48.         //  high limit
    49.         Handles.color = twistColor;
    50.         Handles.DrawSolidArc(jointCenter, twistAxis, twist90, -joint.highTwistLimit.limit, 1);
    51.  
    52.         //  Low limit
    53.         blackColor.a = twistColor.a;
    54.         Handles.color = Color.Lerp(blackColor, twistColor, 0.85f);
    55.         Handles.DrawSolidArc(jointCenter, twistAxis, twist90, -joint.lowTwistLimit.limit, 1);
    56.  
    57.         //  Swing axis
    58.         Vector3 swingAxis = joint.transform.TransformDirection(joint.swingAxis).normalized;
    59.  
    60.        
    61.  
    62.         Handles.color = swing1Color;
    63.         Handles.DrawSolidArc(jointCenter, swingAxis, twistAxis, -joint.swing1Limit.limit, 1);
    64.         Handles.DrawSolidArc(jointCenter, swingAxis, twistAxis, joint.swing1Limit.limit, 1);
    65.  
    66.         //  90 to the Swing axis and twist
    67.         Vector3 swingOrtho = Vector3.Cross(swingAxis, twistAxis);
    68.        
    69.  
    70.         Handles.color = swing2Color;
    71.         Handles.DrawSolidArc(jointCenter, swingOrtho, twistAxis, -joint.swing2Limit.limit, 1);
    72.         Handles.DrawSolidArc(jointCenter, swingOrtho, twistAxis, joint.swing2Limit.limit, 1);
    73.  
    74.     }
    75.     #endregion
    76. }
    77.  
    78.  
     
  8. Enzign

    Enzign

    Joined:
    Aug 20, 2010
    Posts:
    169
    Fantastic script. Thank you very much for sharing this.
     
  9. SunnySunshine

    SunnySunshine

    Joined:
    May 18, 2009
    Posts:
    651
    Absolutely amazing script. Works in Unity 4 too!

    This makes it so much easier to configure the joints.
     
  10. Zerpico

    Zerpico

    Joined:
    Jun 13, 2012
    Posts:
    3
    Thanks, this has been a great help...
     
  11. FlameCow

    FlameCow

    Joined:
    Apr 26, 2013
    Posts:
    1
    Sorry for the bump, but how exactly do you utilize this script?
     
  12. ifisch

    ifisch

    Joined:
    Jul 15, 2012
    Posts:
    24
  13. SilverStorm

    SilverStorm

    Joined:
    Aug 25, 2011
    Posts:
    509
    I was going to write quite a bit about Character Joints but I wasted a lot of time with contradicting information especially from what the docs say and what the results are, I think Unity needs to do an in-depth tutorial in what these aspects actually are.

    PS. Both scripts above are broken.
     
    Last edited: Nov 8, 2015