public void OnSceneGUI()
        {
            if (Application.isPlaying)
            {
                return;
            }
            Transform withStepper = MoveenStep2Editor.withStepper(component.transform);

            if (withStepper == null)
            {
                return;
            }
            MoveenSkelWithBones skel = component.transform.GetComponent <MoveenSkelWithBones>();


            if (skel == null || component.step.detachedComfortPosRel)
            {
                Vector3 oldAbs = withStepper.TransformPoint(component.step.comfortPosRel);
//            Vector3 oldAbs = component.transform.parent.TransformPoint(component.step.bestTargetRel);
                Handles.Label(oldAbs, "comfort position");

                Undo.RecordObject(component, "Moveen target position");
                component.step.comfortPosRel = withStepper.InverseTransformPoint(Handles.PositionHandle(oldAbs, Quaternion.identity));
                //Undo.FlushUndoRecordObjects();seems like done automatically
            }

            if (skel != null && !component.step.detachedComfortPosRel)
            {
                Vector3 tipAbs = skel.transform.TransformPoint(skel.targetPosRel);
                component.step.comfortPosRel = withStepper.rotation.conjug().rotate(tipAbs - withStepper.position);//can't use Inverse, because in the enine - only rotation and translation is used
                component.step.reset(withStepper.position, withStepper.rotation);
            }

            if (GUI.changed)  //to react on comfort position handler (when detached)
            {
                component.step.reset(withStepper.position, withStepper.rotation);
            }
        }
        public override void OnInspectorGUI()
        {
            int legsCount = component.calcActualLegsCount();

            if (component.engine.collectSteppingHistory)
            {
                EditorGUILayout.HelpBox("Don't forget to turn off \"collectSteppingHistory\" as it eats RUNTIME performance and memory", MessageType.Warning);
            }

            if (component.body == null && component.GetComponent <Rigidbody>() == null)
            {
                EditorGUILayout.HelpBox("Add Rigidbody component, or connect this->Body with it", MessageType.Warning);
            }
            if (component.body != null && component.body.GetComponent <Rigidbody>() == null)
            {
                EditorGUILayout.HelpBox("this->Body is connected, but it has no RigidBody component", MessageType.Warning);
            }
            if (component.body != null && component.GetComponent <Rigidbody>() != null && component.body.GetComponent <Rigidbody>())
            {
                EditorGUILayout.HelpBox("Two RigidBody is connected (in this-> and in this->Body->). There can be only one", MessageType.Warning);
            }

            if (legsCount < 2)
            {
                EditorGUILayout.HelpBox("Add legs! Leg is described by GameObjects with LegSkel component on it", MessageType.Warning);
            }
            else
            {
                if (component.engine.leadingLegLeft < 0 || component.engine.leadingLegLeft >= legsCount)
                {
                    EditorGUILayout.HelpBox("Wrong index for Engine -> Leading Leg Left", MessageType.Warning);
                }
                if (component.engine.leadingLegRight < 0 || component.engine.leadingLegRight >= legsCount)
                {
                    EditorGUILayout.HelpBox("Wrong index for Engine -> Leading Leg Right", MessageType.Warning);
                }
            }

            EditorGUILayout.HelpBox("Legs count: " + legsCount, MessageType.None);

            if (component.transform.parent == null)
            {
                EditorGUILayout.HelpBox("Place this game object as a child of another", MessageType.Warning);
            }
            else
            {
                if (GUILayout.Button("Update ProtoModel"))
                {
                    updateProtoModel(component.transform);
                }
                if (GUILayout.Button("Fill ProtoModel"))
                {
                    fillProtoModel(component.transform);
                }
            }

//            if (GUILayout.Button("Create from skeleton")) {
//                createDebugGeometry(t);
//                for (int i = 0; i < t.childCount; i++) {
//                    MoveenLegBase structureDesc = t.GetChild(i).GetComponent<MoveenLegBase>();
//                    if (structureDesc != null) {
//                        for (int b = 0; b < structureDesc.bonesDeltaPos.Count; b++) {
//                            structureDesc.bonesDeltaPos[b] = new Vector3(structureDesc.legSkel.bones[b].r / 2, 0, 0);
//                            structureDesc.bonesDeltaRot[b] = Quaternion.identity;
//                        }
//                        structureDesc.updateData(); //to copy new deltas
//                    }
//                }
//
////            component.copyTransforms();//чтобы пересчитать transform
//            }

            if (GUILayout.Button("Reread layout"))
            {
                component.needsUpdate = true;
            }
            DrawDefaultInspector();

            MoveenStepper5.showInstrumentalInfo = EditorGUILayout.Foldout(MoveenStepper5.showInstrumentalInfo, "instrumental info", true);
            if (MoveenStepper5.showInstrumentalInfo)
            {
                int maxPerformance = 0;
                int performance    = 0;
                addPerformance(ref performance, ref maxPerformance, 50, component.hip != null, "hip connected");
                addPerformance(ref performance, ref maxPerformance, 5 * legsCount, true, legsCount + " legs");
                addPerformance(ref performance, ref maxPerformance, 20, component.engine.forceBipedalEarlyStep, "forceBipedalEaryStep");
                addPerformance(ref performance, ref maxPerformance, 10, component.engine.bipedalForbidPlacement, "bipedalForbidPlacement");
                addPerformance(ref performance, ref maxPerformance, 5, component.engine.protectBodyFromFallthrough, "protectBodyFromFallthrough");
                addPerformance(ref performance, ref maxPerformance, 10, component.engine.bodyLenHelp != 0f, "bodyLenHelp");
//                addPerformance(ref performance, ref maxPerformance, 2, !component.engine.legsCanPull, "legsCanPull");

                //TODO measure numbers
                //TODO...

                EditorGUI.ProgressBar(EditorGUILayout.GetControlRect(), (float)performance / maxPerformance, "CPU use " + performance + " / " + maxPerformance);
                EditorGUILayout.HelpBox("CPU use: " + performance + " / " + maxPerformance + " (lower number - fewer features, more performance)", MessageType.Info);
                MoveenStep2Editor.drawInstrumentalProperties(component.engine);
            }
        }
        private static void Gizmo(MoveenStep2 component, GizmoType gizmoType)
        {
            if (!component.isActiveAndEnabled)
            {
                return;
            }
            Step2 step = component.step;

            if (step.thisTransform == null)
            {
                return;                            //if not updated first time yet
            }
            Transform withStepper = MoveenStep2Editor.withStepper(component.transform);

            Gizmos.color = new Color(0.5f, 0.5f, 0.5f);
            UnityEditorUtils.circle3d(step.bestTargetConservativeAbs, Quaternion.AngleAxis(0, Vector3.up), step.comfortRadius, 20);
            if (!Application.isPlaying)
            {
                if (step.showTrajectory)
                {
                    Gizmos.color = new Color(0, 1, 0);
                    Gizmos.DrawRay(step.posAbs, new Vector3(0, 1, 0) * step.undockTime * step.undockInitialStrength);

                    Vector3 far = step.posAbs + withStepper.rotation.rotate(new Vector3(1, 0, 0)) * step.comfortRadius;
                    Gizmos.color = new Color(1, 0, 0);
                    Gizmos.DrawRay(far, new Vector3(0, 1, 0) * step.targetDockR);

                    Step2 example = new Step2();

                    example.posAbs    = step.posAbs;
                    example.oldPosAbs = step.posAbs;
//                        example.legPosFromStruct = example.legPosAbs;
                    example.undockPause           = step.undockPause;
                    example.targetDockR           = step.targetDockR;
                    example.undockInitialStrength = step.undockInitialStrength;
                    example.undockTime            = step.undockTime;
//                    example.targetUnderground = step.targetUnderground;

                    example.bestTargetProgressiveAbs        = far;
                    example.bestTargetConservativeAbs       = step.posAbs;
                    example.bestTargetConservativeUnprojAbs = step.posAbs;
                    example.legSpeed        = step.stepSpeedMin;
                    example.maxAcceleration = step.maxAcceleration;
                    example.basisAbs        = step.thisTransform.position;
                    example.maxLen          = step.maxLen;
                    example.beginStep(1);
                    example.isExample  = true;
                    example.undockHDif = 1;
                    Vector3 lastPos = step.posAbs;

                    for (int j = 0; j < 1000; j++)
                    {
                        example.tick(1f / 50);
                        Gizmos.color = new Color(0, 0, 1);
                        Gizmos.DrawLine(lastPos, example.posAbs);
                        lastPos = example.posAbs;
                        if (example.posAbs.dist(far) < example.targetDockR * 0.3f)
                        {
                            break;
                        }
                    }
                    Gizmos.color = new Color(0, 1, 0);
                    Gizmos.DrawLine(lastPos, far);
                }
            }

            if (Application.isPlaying)
            {
                Gizmos.color = new Color(0, 1, 0);
                Gizmos.DrawWireSphere(step.bestTargetConservativeAbs, 0.03f);
                Gizmos.color = new Color(1, 1, 0);
                Gizmos.DrawWireSphere(step.bestTargetConservativeUnprojAbs2, 0.08f);
                Gizmos.color = new Color(0, 1, 1);
                Gizmos.DrawWireSphere(step.airTarget, 0.08f);
                Gizmos.color = new Color(1, 0, 0);
                Gizmos.DrawWireSphere(step.bestTargetProgressiveAbs, 0.03f);
                Gizmos.color = new Color(1, 1, 1);
                Gizmos.DrawWireSphere(step.curTarget, 0.05f);

                Gizmos.color = Color.green;

                if (step.wasTooLong)
                {
                    Gizmos.color = Color.red;
                    Gizmos.DrawWireSphere(step.posAbs, 0.2f);
                }
                if (step.dockedState)
                {
                    Gizmos.color = Color.green;
                    Gizmos.DrawWireSphere(step.posAbs, 0.15f);
                }
            }
        }