Esempio n. 1
0
        private static T CreateShape <T>(MenuCommand menuCommand) where T : Shape
        {
            GameObject go     = ObjectFactory.CreateGameObject(typeof(T).Name);
            T          shape  = Undo.AddComponent <T>(go);
            var        camera = SceneView.lastActiveSceneView.camera;
            Ray        ray    = new Ray(camera.transform.position, camera.transform.forward);

            if (!PlaneUtils.RayCastPlaneXZ(ray, out Vector3 pos))
            {
                pos = ray.origin + ray.direction * 10;
            }
            go.transform.position = pos;
            if (menuCommand.context is GameObject parent)
            {
                Undo.SetTransformParent(go.transform, parent.transform, "CreateSharp");
            }
            Selection.activeGameObject = go;
            //EditorGUIUtility.PingObject(go);
            SceneView.lastActiveSceneView.FrameSelected();
            return(shape);
        }
Esempio n. 2
0
        private void OnSceneGUI()
        {
            bool enableEditor = targets.Length == 1;
            var  shape        = target as PolyShape;

            if (worldPoints == null || worldPoints.Length != shape.Points.Count)
            {
                worldPoints = new Vector3[shape.Points.Count];
            }
            Vector3 pos = shape.transform.position;

            pos.y = 0;
            Quaternion rotation = PlaneUtils.TransRotation(shape.transform.rotation);
            Matrix4x4  matrix   = Matrix4x4.TRS(pos, rotation, Vector3.one);

            for (int i = 0; i < shape.Points.Count; ++i)
            {
                worldPoints[i] = matrix.MultiplyPoint(shape.Points[i]);
            }

            //计算鼠标点击在XZ平面的点
            Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);

            if (!PlaneUtils.RayCastPlaneXZ(ray, out Vector3 mousePos))
            {
                return;//鼠标没有点击在XZ平面
            }
            var     result     = PlaneUtils.ClosestPointToPolyLine(mousePos, worldPoints);
            Vector3 closePoint = result.Point;
            int     index      = result.Index;

            using (new Handles.DrawingScope(Color.green))
            {
                //画边缘线
                for (int i = 0; i < worldPoints.Length; ++i)
                {
                    int nextIndex = i + 1;
                    if (nextIndex == shape.Points.Count)
                    {
                        nextIndex = 0;
                    }
                    Vector3 pt = worldPoints[i];
                    Handles.DrawLine(pt, worldPoints[nextIndex]);
                    if (enableEditor)
                    {
                        //点位置编辑
                        float handleSize = HandleUtility.GetHandleSize(pt) * 0.05f;
                        EditorGUI.BeginChangeCheck();
                        pt = Handles.FreeMoveHandle(pt, Quaternion.identity, handleSize, new Vector3(1, 0, 1), Handles.DotHandleCap);
                        if (EditorGUI.EndChangeCheck())
                        {
                            Undo.RecordObject(shape, "move polygon point");
                            EditorUtility.SetDirty(shape);
                            pt              = matrix.inverse.MultiplyPoint(pt);
                            pt.y            = 0;
                            worldPoints[i]  = pt;
                            shape.Points[i] = pt;
                            shape.SetDirty();
                        }
                    }
                }
                if (!enableEditor)
                {
                    return;
                }
                if (Event.current.control)
                {//移除点
                    if (worldPoints.Length > 3)
                    {
                        int removeIndex = index + 1;
                        if (removeIndex == worldPoints.Length)
                        {
                            removeIndex = 0;
                        }

                        int preIndex = removeIndex - 1;
                        if (preIndex < 0)
                        {
                            preIndex = worldPoints.Length - 1;
                        }
                        int nextIndex = removeIndex + 1;
                        if (nextIndex == worldPoints.Length)
                        {
                            nextIndex = 0;
                        }
                        Handles.DrawLine(worldPoints[preIndex], worldPoints[nextIndex]);
                        using (new Handles.DrawingScope(Color.red))
                        {
                            Handles.DrawAAPolyLine(5, worldPoints[preIndex], worldPoints[removeIndex]);
                            Handles.DrawAAPolyLine(5, worldPoints[nextIndex], worldPoints[removeIndex]);
                            float handleSize = HandleUtility.GetHandleSize(worldPoints[removeIndex]) * 0.05f;
                            var   pt1        = HandleUtility.WorldToGUIPoint(worldPoints[removeIndex]);
                            var   pt2        = HandleUtility.WorldToGUIPoint(mousePos);
                            float pickSize   = Vector2.Distance(pt1, pt2) + 0.1f;
                            if (Handles.Button(worldPoints[removeIndex], Quaternion.identity, handleSize, pickSize, Handles.DotHandleCap))
                            {
                                Undo.RecordObject(shape, "delete polygon point");
                                EditorUtility.SetDirty(shape);
                                shape.Points.RemoveAt(removeIndex);
                                shape.SetDirty();
                                Event.current.Use();
                            }
                        }
                    }
                }
                else if (Event.current.shift && (result.SegmentLength * result.NormalLength) > 0.1f && (result.SegmentLength * result.NormalLength) < (result.SegmentLength - 0.1f))
                {//添加点
                    {
                        float handleSize = HandleUtility.GetHandleSize(closePoint) * 0.08f;
                        //画距离鼠标最近的点
                        Handles.SphereHandleCap(0, closePoint, Quaternion.identity, handleSize, Event.current.type);
                    }

                    int insertIndex = index + 1;
                    if (insertIndex == worldPoints.Length)
                    {
                        insertIndex = 0;
                    }
                    using (new Handles.DrawingScope(Color.white))
                    {
                        Handles.DrawLine(mousePos, worldPoints[index]);
                        Handles.DrawLine(mousePos, worldPoints[insertIndex]);
                        float handleSize = HandleUtility.GetHandleSize(mousePos) * 0.05f;
                        if (Handles.Button(mousePos, Quaternion.identity, handleSize, 0.1f, Handles.DotHandleCap))
                        {
                            Undo.RecordObject(shape, "add polygon point");
                            EditorUtility.SetDirty(shape);

                            var pt = matrix.inverse.MultiplyPoint(mousePos);
                            shape.Points.Insert(insertIndex, pt);
                            shape.SetDirty();
                            Event.current.Use();
                        }
                    }
                }
            }
            SceneView.RepaintAll();
        }