private void RenderAngleLimits
        (
            Vector2 origin,
            float lineLength,
            Vector2 pivotSpaceVector,
            AngleLimits angleLimits,
            Color limitColor
        )
        {
            Inspector3DRenderer.DrawArrow(origin, new Vector2(origin.x, origin.y + lineLength), Color.gray);

            System.Func <float, Vector2> getLimitEndPoint = degrees =>
            {
                var minRadians = Mathf.Deg2Rad * degrees;
                var offset     = new Vector2(Mathf.Sin(minRadians), Mathf.Cos(minRadians));
                return(origin + lineLength * offset);
            };

            if (!angleLimits.active)
            {
                limitColor = Color.grey;
            }
            var minPosition = getLimitEndPoint(angleLimits.min);

            Inspector3DRenderer.DrawArrow(origin, minPosition, limitColor);
            var maxPosition = getLimitEndPoint(angleLimits.max);

            Inspector3DRenderer.DrawArrow(origin, maxPosition, limitColor);

            if (Application.isPlaying)
            {
                Inspector3DRenderer.DrawArrow(origin, origin + lineLength * pivotSpaceVector, Color.white);
            }
        }
        private void RenderAngleLimitVisualization()
        {
            var bone = (SpringBone)target;

            if (bone.yAngleLimits.active == false &&
                bone.zAngleLimits.active == false)
            {
                return;
            }

            if (renderer == null)
            {
                renderer = new Inspector3DRenderer();
            }

            var useDoubleHeightRect = bone.yAngleLimits.min <-90f ||
                                                             bone.yAngleLimits.max> 90f ||
                                      bone.zAngleLimits.min <-90f ||
                                                             bone.zAngleLimits.max> 90f;

            GUILayout.BeginVertical("box");
            GUILayout.BeginHorizontal();
            GUILayout.Label("Y 軸角度制限");
            GUILayout.Label("Z 軸角度制限");
            GUILayout.EndHorizontal();
            EditorGUILayout.Space();
            const float DefaultRectHeight = 100f;
            var         rect = GUILayoutUtility.GetRect(
                200f, useDoubleHeightRect ? (2f * DefaultRectHeight) : DefaultRectHeight);

            GUILayout.EndVertical();

            if (Event.current.type != EventType.Repaint)
            {
                return;
            }

            renderer.BeginRender(rect);
            GL.Begin(GL.LINES);

            rect.x = 0f;
            rect.y = 0f;
            Inspector3DRenderer.DrawHollowRect(rect, Color.white);

            const float LineLength       = 0.8f * DefaultRectHeight;
            var         xOffset          = 0.25f * rect.width;
            var         yOffset          = useDoubleHeightRect ? rect.center.y : (rect.y + 0.1f * DefaultRectHeight);
            var         halfWidth        = rect.width * 0.5f;
            var         pivotTransform   = bone.GetPivotTransform();
            var         pivotSpaceVector = pivotTransform.InverseTransformVector(
                (bone.CurrentTipPosition - bone.transform.position).normalized);

            var yLimitColor  = new Color(0.2f, 1f, 0.2f);
            var yLimitVector = new Vector2(-pivotSpaceVector.y, -pivotSpaceVector.x);
            var yOrigin      = new Vector2(xOffset, yOffset);

            RenderAngleLimits(yOrigin, LineLength, yLimitVector, bone.yAngleLimits, yLimitColor);

            var zLimitColor  = new Color(0.7f, 0.7f, 1f);
            var zLimitVector = new Vector2(-pivotSpaceVector.z, -pivotSpaceVector.x);
            var zOrigin      = new Vector2(xOffset + halfWidth, yOffset);

            RenderAngleLimits(zOrigin, LineLength, zLimitVector, bone.zAngleLimits, zLimitColor);

            GL.End();
            renderer.EndRender();
        }