private void DrawClosestPointOnLine()
        {
            Event currentEvent = Event.current;

            if (currentEvent.modifiers == EventModifiers.Control)
            {
                Vector3 pointPos  = HandleUtility.ClosestPointToPolyLine(lines);
                Color   prevColor = Handles.color;
                Handles.color = sphereColor;
                Handles.DrawSolidDisc(pointPos, Camera.current.transform.forward, HandleUtility.GetHandleSize(pointPos) * 0.1f);
                Handles.color = prevColor;
                HandleUtility.Repaint();


                if (currentEvent.type == EventType.MouseDown && currentEvent.button == 0)
                {
                    GUIUtility.hotControl = 0;
                    int index = GetIndextOfClosestLine(pointPos);
                    pointsProperty.InsertArrayElementAtIndex(index);
                    serializedObject.ApplyModifiedProperties();
                    waypoints[index] = pointPos;
                    CreateSegments();
                    CreateLines();
                    currentEvent.Use();
                }
            }
        }
示例#2
0
    protected Vector3 ClosestPoint(Transform t, Vector2[] verts)
    {
        // Duplicate the verts list and make it into a loop.
        var loop = new List <Vector2>(verts);

        loop.Add(verts[0]);
        Vector3[] arr = loop.Select <Vector2, Vector3>((arg) => (Vector3)t.TransformPoint(arg)).ToArray();
        return(HandleUtility.ClosestPointToPolyLine(arr));
    }
示例#3
0
    void OnSceneGUI()
    {
        Rope rope = (target as Rope);

        Vector3[] localPoints = rope.nodes.ToArray();
        Vector3[] worldPoints = new Vector3[rope.nodes.Count];
        for (int i = 0; i < worldPoints.Length; i++)
        {
            worldPoints[i] = rope.transform.TransformPoint(localPoints[i]);
        }
        DrawPolyLine(worldPoints);
        DrawNodes(rope, worldPoints);
        DrawHinges(rope);

        if (Event.current.shift)
        {
            //Adding Points
            Vector3 mousePos          = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin;
            Vector3 polyLocalMousePos = rope.transform.InverseTransformPoint(mousePos);
            Vector3 nodeOnPoly        = HandleUtility.ClosestPointToPolyLine(worldPoints);
            float   handleSize        = HandleUtility.GetHandleSize(nodeOnPoly);
            int     nodeIndex         = FindNodeIndex(worldPoints, nodeOnPoly);
            Handles.DrawLine(worldPoints[nodeIndex - 1], mousePos);
            Handles.DrawLine(worldPoints[nodeIndex], mousePos);
            if (Handles.Button(mousePos, Quaternion.identity, handleSize * 0.1f, handleSize, HandleFunc))
            {
                polyLocalMousePos.z = 0;
                Undo.RecordObject(rope, "Insert Node");
                rope.nodes.Insert(nodeIndex, polyLocalMousePos);
                UpdateRope(rope);
                Event.current.Use();
            }
        }
        if (Event.current.control && rope.nodes.Count > 2)
        {
            //Deleting Points
            int indexToDelete = FindNearestNodeToMouse(worldPoints);
            Handles.color = Color.red;
            float handleSize = HandleUtility.GetHandleSize(worldPoints[0]);
            if (Handles.Button(worldPoints[indexToDelete], Quaternion.identity, handleSize * 0.09f, handleSize, DeleteHandleFunc))
            {
                Undo.RecordObject(rope, "Remove Node");
                rope.nodes.RemoveAt(indexToDelete);
                indexToDelete = -1;
                UpdateRope(rope);
                Event.current.Use();
            }
            Handles.color = Color.white;
        }
        if (ropePosition != rope.transform.position)
        {
            ropePosition = rope.transform.position;
            UpdateEndsJoints(rope);
        }
    }
示例#4
0
    void OnSceneGUI()
    {
        PointManager.Instance = (target as PointManager);
        Vector3[] localPoints = PointManager.Instance.nodes.ToArray();
        Vector3[] worldPoints = new Vector3[PointManager.Instance.nodes.Count];

        for (int i = 0; i < worldPoints.Length; i++)
        {
            worldPoints[i] = PointManager.Instance.transform.TransformPoint(localPoints[i]);
        }

        DrawPoints(worldPoints);
        DrawNodes(worldPoints);

        #region AddPoint
        if (Event.current.shift)
        {
            Vector3 mousePos           = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin;
            Vector3 pointLocalMousePos = PointManager.Instance.transform.InverseTransformPoint(mousePos);
            Vector3 nodeOnPoly         = HandleUtility.ClosestPointToPolyLine(worldPoints);

            float handleSize = HandleUtility.GetHandleSize(nodeOnPoly);
            int   nodeIndex  = FindNodeIndex(worldPoints, nodeOnPoly);

            Handles.DrawLine(worldPoints[nodeIndex - 1], mousePos);
            Handles.DrawLine(worldPoints[nodeIndex], mousePos);

            if (Handles.Button(mousePos, Quaternion.identity, handleSize * .1f, handleSize, HandleFunc))
            {
                pointLocalMousePos.y = 1f;
                Undo.RecordObject(PointManager.Instance, "InsertNode");
                PointManager.Instance.nodes.Insert(nodeIndex, pointLocalMousePos);
                Event.current.Use();
            }
        }
        #endregion

        #region DeletePoint
        if (Event.current.control)
        {
            int indexToDelete = FindeNearestNodeToMouse(worldPoints);
            Handles.color = Color.red;
            float handleSize = HandleUtility.GetHandleSize(worldPoints[0]);

            if (Handles.Button(worldPoints[indexToDelete], Quaternion.identity, handleSize * 0.09f, handleSize, DeleteHandle))
            {
                Undo.RecordObject(PointManager.Instance, "Remove Node");
                PointManager.Instance.nodes.RemoveAt(indexToDelete);
                indexToDelete = -1;
                Event.current.Use();
            }
            Handles.color = Color.white;
        }
        #endregion
    }
示例#5
0
 /// <summary>
 /// Draws the glyph add-point-to-edge handles.
 /// </summary>
 public void DrawGlyphEdgeHandles()
 {
     serializedObject.Update();
     handleSize = HandleUtility.GetHandleSize(Vector3.zero) * 0.04f;
     if (strokes != null)
     {
         SerializedProperty child = strokes.Copy();
         child.Next(true);
         float bestDist = float.PositiveInfinity;
         SerializedProperty bestPoint = null;
         foreach (SerializedProperty childStroke in child)
         {
             SerializedProperty childArray = childStroke.Copy();
             childArray.Next(true); childArray.Next(true);
             SerializedProperty prev, curr = childArray.GetArrayElementAtIndex(0);
             for (int p = 1; p < childArray.arraySize; p++)
             {
                 prev = curr; curr = childArray.GetArrayElementAtIndex(p);
                 float dist = HandleUtility.DistanceToLine(prev.vector2Value, curr.vector2Value);
                 if (dist < bestDist)
                 {
                     bestDist  = dist;
                     bestPoint = prev;
                 }
             }
         }
         if (bestDist < 5f)
         {
             SerializedProperty nextPoint    = bestPoint.Copy(); nextPoint.Next(false);
             Vector3            closestPoint = HandleUtility.ClosestPointToPolyLine(bestPoint.vector2Value, nextPoint.vector2Value);
             if (Handles.Button(closestPoint, Quaternion.identity, handleSize, handleSize, Handles.DotHandleCap))
             {
                 //dup and move
                 if (bestPoint.DuplicateCommand())
                 {
                     bestPoint.Next(false);
                     bestPoint.vector2Value = (Vector2)closestPoint;
                 }
             }
         }
     }
     serializedObject.ApplyModifiedProperties();
 }
示例#6
0
        private void DisplayCollider()
        {
            Event e = Event.current;

            if (Tileset.SelectedBrushId != Tileset.k_BrushId_Default)
            {
                EditorGUILayout.LabelField("Brush tile editing not allowed", EditorStyles.boldLabel);
                return;
            }

            bool isMultiselection = Tileset.TileSelection != null;
            bool saveChanges      = false;
            Tile selectedTile     = isMultiselection ? Tileset.Tiles[(int)(Tileset.TileSelection.selectionData[0] & Tileset.k_TileDataMask_TileId)] : Tileset.SelectedTile;

            if (e.type == EventType.MouseDown)
            {
                m_isDragging = true;
                if (selectedTile.collData.vertices != null)
                {
                    m_savedVertexData = new Vector2[selectedTile.collData.vertices.Length];
                    selectedTile.collData.vertices.CopyTo(m_savedVertexData, 0);
                }
            }
            else if (e.type == EventType.MouseUp)
            {
                m_isDragging = false;
            }

            Tileset.BackgroundColor = EditorGUILayout.ColorField(Tileset.BackgroundColor);
            if (m_prevBgColor != Tileset.BackgroundColor || Styles.Instance.colliderBgStyle.normal.background == null)
            {
                m_prevBgColor = Tileset.BackgroundColor;
                if (Styles.Instance.colliderBgStyle.normal.background == null)
                {
                    Styles.Instance.colliderBgStyle.normal.background = new Texture2D(1, 1)
                    {
                        hideFlags = HideFlags.DontSave
                    }
                }
                ;
                Styles.Instance.colliderBgStyle.normal.background.SetPixel(0, 0, Tileset.BackgroundColor);
                Styles.Instance.colliderBgStyle.normal.background.Apply();
            }

            float aspectRatio = Tileset.TilePxSize.x / Tileset.TilePxSize.y;
            float padding     = 2; // pixel size of the border around the tile
            //Rect rCollArea = GUILayoutUtility.GetRect(1, 1, GUILayout.Width(EditorGUIUtility.currentViewWidth), GUILayout.Height(EditorGUIUtility.currentViewWidth / aspectRatio));
            Rect rCollArea = GUILayoutUtility.GetRect(1, 1, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));

            GUI.BeginGroup(rCollArea, Styles.Instance.colliderBgStyle);
            if (e.type == EventType.Repaint)
            {
                float pixelSize = rCollArea.width / (Tileset.TilePxSize.x + 2 * padding);
                m_mousePos     = e.mousePosition;
                m_rTile        = new Rect(padding * pixelSize, padding * pixelSize, rCollArea.width - 2 * padding * pixelSize, (rCollArea.width / aspectRatio) - 2 * padding * pixelSize);
                m_rTile.height = Mathf.Min(m_rTile.height, rCollArea.height - 2 * padding * pixelSize);
                m_rTile.width  = (m_rTile.height * aspectRatio);
            }
            GUI.color = new Color(1f, 1f, 1f, 0.1f);
            GUI.DrawTexture(m_rTile, EditorGUIUtility.whiteTexture);
            GUI.color = Color.white;
            if (isMultiselection)
            {
                foreach (uint tileData in Tileset.TileSelection.selectionData)
                {
                    int  tileId = (int)(tileData & Tileset.k_TileDataMask_TileId);
                    Tile tile   = (tileId != Tileset.k_TileId_Empty) ? Tileset.Tiles[tileId] : null;
                    if (tile != null)
                    {
                        GUI.color = new Color(1f, 1f, 1f, 1f / Tileset.TileSelection.selectionData.Count);
                        GUI.DrawTextureWithTexCoords(m_rTile, Tileset.AtlasTexture, tile.uv);
                    }
                }
                GUI.color = Color.white;
            }
            else
            {
                GUI.DrawTextureWithTexCoords(m_rTile, Tileset.AtlasTexture, selectedTile.uv);
            }

            Color savedHandleColor = Handles.color;

            if (selectedTile.collData.type != eTileCollider.None)
            {
                Vector2[] collVertices = selectedTile.collData.type == eTileCollider.Full ? s_fullCollTileVertices : selectedTile.collData.vertices;
                if (collVertices == null || collVertices.Length == 0)
                {
                    collVertices = selectedTile.collData.vertices = new Vector2[s_fullCollTileVertices.Length];
                    Array.Copy(s_fullCollTileVertices, collVertices, s_fullCollTileVertices.Length);
                    EditorUtility.SetDirty(Tileset);
                }

                // Fix and snap positions
                for (int i = 0; i < collVertices.Length; ++i)
                {
                    Vector2 s0 = collVertices[i];
                    s0.x            = Mathf.Clamp01(Mathf.Round(s0.x * Tileset.TilePxSize.x) / Tileset.TilePxSize.x);
                    s0.y            = Mathf.Clamp01(Mathf.Round(s0.y * Tileset.TilePxSize.y) / Tileset.TilePxSize.y);
                    collVertices[i] = s0;
                }

                // Draw edges
                Vector3[] polyEdges = new Vector3[collVertices.Length + 1];
                for (int i = 0; i < collVertices.Length; ++i)
                {
                    Vector2 s0 = collVertices[i];
                    s0.x = m_rTile.x + m_rTile.width * s0.x; s0.y = m_rTile.yMax - m_rTile.height * s0.y;
                    Vector2 s1 = collVertices[(i + 1) % collVertices.Length];
                    s1.x = m_rTile.x + m_rTile.width * s1.x; s1.y = m_rTile.yMax - m_rTile.height * s1.y;

                    polyEdges[i]     = s0;
                    polyEdges[i + 1] = s1;

                    Handles.color = Color.green;
                    Handles.DrawLine(s0, s1);
                    //Draw normals
                    {
                        Handles.color = Color.white;
                        Vector3 normPos = (s0 + s1) / 2f;
                        Handles.DrawLine(normPos, normPos + Vector3.Cross(s1 - s0, Vector3.forward).normalized *m_rTile.yMin);
                    }

                    Handles.color = savedHandleColor;
                }

                float pixelSize = m_rTile.width / Tileset.TilePxSize.x;
                if (selectedTile.collData.type == eTileCollider.Polygon)
                {
                    bool isAddingVertexOn   = !m_isDragging && e.shift && m_activeVertexIdx == -1;
                    bool isRemovingVertexOn = !m_isDragging && ((Application.platform == RuntimePlatform.OSXEditor)? e.command : e.control) && collVertices.Length > 3;
                    if (isRemovingVertexOn && m_activeVertexIdx != -1 && e.type == EventType.MouseUp)
                    {
                        selectedTile.collData.vertices = new Vector2[collVertices.Length - 1];
                        for (int i = 0, j = 0; i < collVertices.Length; ++i)
                        {
                            if (i == m_activeVertexIdx)
                            {
                                continue;
                            }
                            selectedTile.collData.vertices[j] = collVertices[i];
                            ++j;
                        }
                        collVertices      = selectedTile.collData.vertices;
                        m_activeVertexIdx = -1;
                    }

                    float minDist = float.MaxValue;
                    if (!m_isDragging)
                    {
                        m_activeVertexIdx = -1;
                    }
                    for (int i = 0; i < collVertices.Length; ++i)
                    {
                        Vector2 s0 = collVertices[i];
                        s0.x = m_rTile.x + m_rTile.width * s0.x;
                        s0.y = m_rTile.yMax - m_rTile.height * s0.y;

                        if (m_isDragging)
                        {
                            if (i == m_activeVertexIdx)
                            {
                                s0   = m_mousePos;
                                s0  -= m_rTile.position;
                                s0.x = Mathf.Clamp(Mathf.Round(s0.x / pixelSize) * pixelSize, 0, m_rTile.width);
                                s0.y = Mathf.Clamp(Mathf.Round(s0.y / pixelSize) * pixelSize, 0, m_rTile.height);
                                s0  += m_rTile.position;
                                collVertices[i].x = Mathf.Clamp01((s0.x - m_rTile.x) / m_rTile.width);
                                collVertices[i].y = Mathf.Clamp01((s0.y - m_rTile.yMax) / -m_rTile.height);
                            }
                        }
                        else
                        {
                            float dist = Vector2.Distance(m_mousePos, s0);
                            if (dist <= minDist && dist < Styles.Instance.collVertexHandleStyle.normal.background.width)
                            {
                                minDist           = dist;
                                m_activeVertexIdx = i;
                            }
                        }

                        if (e.type == EventType.Repaint)
                        {
                            if (i == m_activeVertexIdx)
                            {
                                Styles.Instance.vertexCoordStyle.fontSize = (int)(Mathf.Min(10f, m_rTile.yMin / 2f));
                                GUI.Label(new Rect(0, 0, m_rTile.width, m_rTile.yMin), Vector2.Scale(collVertices[i], Tileset.TilePxSize).ToString(), Styles.Instance.vertexCoordStyle);
                            }
                            GUI.color = m_activeVertexIdx == i ? (isRemovingVertexOn ? Color.red : Color.cyan) : new Color(0.7f, 0.7f, 0.7f, 0.8f);
                            Styles.Instance.collVertexHandleStyle.Draw(new Rect(s0.x - Styles.Instance.collVertexHandleStyle.normal.background.width / 2, s0.y - Styles.Instance.collVertexHandleStyle.normal.background.height / 2, 1, 1), i.ToString(), false, false, false, false);
                            GUI.color = Color.white;
                        }
                    }

                    if (isAddingVertexOn)
                    {
                        int     segmentIdx;
                        Vector2 newVertexPos = ClosestPointToPolyLine(polyEdges, out segmentIdx);

                        if (e.type == EventType.MouseUp)
                        {
                            selectedTile.collData.vertices = new Vector2[collVertices.Length + 1];
                            segmentIdx = (segmentIdx + 1) % selectedTile.collData.vertices.Length;
                            for (int i = 0, j = 0; i < selectedTile.collData.vertices.Length; ++i)
                            {
                                if (segmentIdx == i)
                                {
                                    newVertexPos.x = Mathf.Clamp(Mathf.Round(newVertexPos.x / pixelSize) * pixelSize, m_rTile.x, m_rTile.xMax);
                                    newVertexPos.y = Mathf.Clamp(Mathf.Round(newVertexPos.y / pixelSize) * pixelSize, m_rTile.y, m_rTile.yMax);
                                    selectedTile.collData.vertices[i].x = Mathf.Clamp01((newVertexPos.x - m_rTile.x) / m_rTile.width);
                                    selectedTile.collData.vertices[i].y = Mathf.Clamp01((newVertexPos.y - m_rTile.yMax) / -m_rTile.height);
                                }
                                else
                                {
                                    selectedTile.collData.vertices[i] = collVertices[j];
                                    ++j;
                                }
                            }
                            collVertices      = selectedTile.collData.vertices;
                            m_activeVertexIdx = -1;
                        }
                        else if (e.type == EventType.Repaint)
                        {
                            GUI.color = new Color(0.7f, 0.7f, 0.7f, 0.8f);
                            Styles.Instance.collVertexHandleStyle.Draw(new Rect(newVertexPos.x - Styles.Instance.collVertexHandleStyle.normal.background.width / 2, newVertexPos.y - Styles.Instance.collVertexHandleStyle.normal.background.height / 2, 1, 1), segmentIdx.ToString(), false, false, false, false);
                            GUI.color = Color.white;
                        }
                    }
                }

                if (e.type == EventType.MouseUp)
                {
                    saveChanges = true;
                    //remove duplicated vertex
                    selectedTile.collData.vertices = selectedTile.collData.vertices.Distinct().ToArray();
                    if (selectedTile.collData.vertices.Length <= 2)
                    {
                        selectedTile.collData.vertices = m_savedVertexData;
                    }
                }
            }

            GUI.EndGroup();

            if (GUILayout.Button("Reverse Normals"))
            {
                selectedTile.collData.vertices = selectedTile.collData.vertices.Reverse().ToArray();
            }

            EditorGUILayout.Space();

            string helpInfo =
                //"Using Polygon collider:" + "\n" +
                "  - Click and drag over a vertex to move it" + "\n" +
                "  - Hold Shift + Click for adding a new vertex" + "\n" +
                "  - Hold " + ((Application.platform == RuntimePlatform.OSXEditor)? "Command" : "Ctrl") + " + Click for removing a vertex. (should be more than 3)" + "\n" +
                "  - Check the normals for each edge. The normal is displayed in the collision side" + "\n" +
                "";

            s_showHelp = EditorGUILayout.Foldout(s_showHelp, "Help");
            if (s_showHelp)
            {
                EditorGUILayout.HelpBox(helpInfo, MessageType.Info);
            }

            //+++ Collider Settings
            float savedLabelWidth = EditorGUIUtility.labelWidth;

            EditorGUIUtility.labelWidth = 40;
            if (isMultiselection)
            {
                EditorGUILayout.LabelField("* Multi-selection Edition", EditorStyles.boldLabel);
            }
            EditorGUILayout.BeginHorizontal(GUILayout.MinWidth(140));
            {
                EditorGUILayout.LabelField("Collider Data", EditorStyles.boldLabel);
                if (GUILayout.Button("Copy", GUILayout.Width(50)))
                {
                    m_copiedColliderData = selectedTile.collData.Clone();
                }
                if (GUILayout.Button("Paste", GUILayout.Width(50)))
                {
                    selectedTile.collData = m_copiedColliderData.Clone();
                    saveChanges           = true;
                }
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();
            EditorGUIUtility.labelWidth = 100;
            EditorGUI.BeginChangeCheck();

            //selectedTile.collData.type = (eTileCollider)EditorGUILayout.EnumPopup("Collider Type", selectedTile.collData.type);
            EditorGUILayout.LabelField("Collider Type:", EditorStyles.boldLabel);
            EditorGUI.indentLevel += 2;
            string[] tileColliderNames = System.Enum.GetNames(typeof(eTileCollider));

            selectedTile.collData.type = (eTileCollider)GUILayout.Toolbar((int)selectedTile.collData.type, tileColliderNames);
            EditorGUI.indentLevel     -= 2;

            saveChanges |= EditorGUI.EndChangeCheck();
            EditorGUIUtility.labelWidth = savedLabelWidth;
            //---

            //Save changes
            if (saveChanges)
            {
                if (isMultiselection)
                {
                    for (int i = 0; i < Tileset.TileSelection.selectionData.Count; ++i)
                    {
                        Tileset.Tiles[(int)(Tileset.TileSelection.selectionData[i] & Tileset.k_TileDataMask_TileId)].collData = selectedTile.collData.Clone();
                    }
                }
                EditorUtility.SetDirty(Tileset);
            }
        }

        /// <summary>
        //     Get the point on a polyline (in 3D space) which is closest to the current
        //     mouse position. And returns the segment index ( the vertex index of the segment with the closest point )
        /// </summary>
        /// <param name="vertices"></param>
        /// <param name="closedSegmentIdx"></param>
        /// <returns></returns>
        Vector3 ClosestPointToPolyLine(Vector3[] vertices, out int closedSegmentIdx)
        {
            float minDist = float.MaxValue;

            closedSegmentIdx = 0;
            for (int i = 0; i < vertices.Length - 1; ++i)
            {
                float dist = HandleUtility.DistanceToLine(vertices[i], vertices[i + 1]);
                if (dist < minDist)
                {
                    minDist          = dist;
                    closedSegmentIdx = i;
                }
            }
            return(HandleUtility.ClosestPointToPolyLine(vertices));
        }
        private void DoTools()
        {
            if (Event.current.rawType == EventType.KeyDown && Event.current.isKey && !isDown)
            {
                tool = curve.tool;
                KeyCode key = Event.current.keyCode;
                if (key == KeyCode.A)
                {
                    curve.tool = PaintTools.Add;
                }
                else if (key == KeyCode.D)
                {
                    curve.tool = PaintTools.Remove;
                }
                else if (key == KeyCode.I)
                {
                    curve.tool = PaintTools.Insert;
                }
                isDown = true;
                EditorUtility.SetDirty(curve);
                Event.current.Use();
            }
            else if (Event.current.rawType == EventType.KeyUp)
            {
                curve.tool = tool;
                isDown     = false;
                EditorUtility.SetDirty(curve);
                Event.current.Use();
            }
            switch (curve.tool)
            {
            case PaintTools.Add:
                EditorGUIUtility.AddCursorRect(new Rect(0, 0, Screen.width, Screen.height), MouseCursor.ArrowPlus);
                SceneView.RepaintAll();

                if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
                {
                    GUIUtility.hotControl = 0;
                    Plane plane = new Plane(Camera.current.transform.forward, Vector3.zero);
                    float dist  = 0f;
                    Ray   ray   = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                    if (plane.Raycast(ray, out dist))
                    {
                        Vector3 newPosition = ray.GetPoint(dist);
                        curve.AddPointAt(curve.transform.InverseTransformPoint(newPosition));
                        curve.SendMessage("OnRectTransformDimensionsChange", SendMessageOptions.DontRequireReceiver);
                        EditorUtility.SetDirty(curve);
                    }
                    Event.current.Use();
                }
                break;

            case PaintTools.Insert:
                int   limit = curve.resolution + 1;
                float _res  = curve.resolution;
                if (curve.count > 1)
                {
                    for (int index = 0; index < curve.count - 1; index++)
                    {
                        BezierPoint p1           = curve[index];
                        BezierPoint p2           = curve[index + 1];
                        Vector3     lastPoint    = p1.localPosition;
                        Vector3     currentPoint = Vector3.zero;

                        for (int i = 1; i < limit; i++)
                        {
                            currentPoint = BezierCurve.GetPoint(p1, p2, i / _res);
                            if (HandleUtility.DistanceToLine(curve.transform.TransformPoint(currentPoint), curve.transform.TransformPoint(lastPoint)) < 2f && Vector2.Distance(Event.current.mousePosition, HandleUtility.WorldToGUIPoint(curve.transform.TransformPoint(p1.localPosition))) > 5f && Vector2.Distance(Event.current.mousePosition, HandleUtility.WorldToGUIPoint(curve.transform.TransformPoint(p2.localPosition))) > 5f)
                            {
                                EditorGUIUtility.AddCursorRect(new Rect(0, 0, Screen.width, Screen.height), MouseCursor.ArrowPlus);
                                SceneView.RepaintAll();
                                if (Event.current.type == EventType.MouseDown)
                                {
                                    GUIUtility.hotControl = 0;

                                    curve.AddPointAt(index + 1, HandleUtility.ClosestPointToPolyLine(lastPoint, currentPoint));
                                    curve.SendMessage("OnRectTransformDimensionsChange", SendMessageOptions.DontRequireReceiver);
                                    EditorUtility.SetDirty(curve);
                                    Event.current.Use();
                                }
                            }
                            lastPoint = currentPoint;
                        }
                    }
                }
                break;

            case PaintTools.Remove:
                if (curve.count > 2)
                {
                    for (int index = 0; index < curve.count; index++)
                    {
                        BezierPoint p        = curve[index];
                        Vector2     guiPoint = HandleUtility.WorldToGUIPoint(curve.transform.TransformPoint(p.localPosition));

                        if (Vector2.Distance(Event.current.mousePosition, guiPoint) < 5f)
                        {
                            EditorGUIUtility.AddCursorRect(new Rect(0, 0, Screen.width, Screen.height), MouseCursor.ArrowMinus);
                            SceneView.RepaintAll();
                            if (Event.current.type == EventType.MouseDown)
                            {
                                GUIUtility.hotControl = 0;
                                curve.RemovePoint(p);
                                curve.SendMessage("OnRectTransformDimensionsChange", SendMessageOptions.DontRequireReceiver);
                                EditorUtility.SetDirty(curve);
                                Event.current.Use();
                            }
                        }
                    }
                }
                break;
            }
        }
        /// <summary>
        /// Construct & display the curve from DragPointsHandler control points
        /// Find the curve traveller position along the curve
        /// </summary>
        ///
        /// <remarks>
        /// Will use the DragPointExposure from the handler's item to display slingshot segments accordingly
        /// Will update handler's curve traveller position and control point base index for point insertion
        /// </remarks>
        private void DisplayCurve()
        {
            List <Vector3>[] controlPointsSegments = new List <Vector3> [_handler.ControlPoints.Count].Select(item => new List <Vector3>()).ToArray();

            // Display Curve & handle curve traveller
            if (_handler.ControlPoints.Count > 1)
            {
                var transformedDPoints = new List <DragPointData>();
                foreach (var controlPoint in _handler.ControlPoints)
                {
                    var newDp = new DragPointData(controlPoint.DragPoint)
                    {
                        Center = controlPoint.WorldPos.ToVertex3D()
                    };
                    transformedDPoints.Add(newDp);
                }

                var vAccuracy = Vector3.one;
                vAccuracy = _handler.Transform.localToWorldMatrix.MultiplyVector(vAccuracy);
                var accuracy = Mathf.Abs(vAccuracy.x * vAccuracy.y * vAccuracy.z);
                accuracy *= HandleUtility.GetHandleSize(_handler.CurveTravellerPosition) * ControlPoint.ScreenRadius;
                var vVertex = DragPoint.GetRgVertex <RenderVertex3D, CatmullCurve3DCatmullCurveFactory>(
                    transformedDPoints.ToArray(), _handler.DragPointInspector.PointsAreLooping, accuracy
                    );

                if (vVertex.Length > 0)
                {
                    // Fill Control points paths
                    ControlPoint currentControlPoint = null;
                    foreach (var v in vVertex)
                    {
                        if (v.IsControlPoint)
                        {
                            if (currentControlPoint != null)
                            {
                                controlPointsSegments[currentControlPoint.Index].Add(v.ToUnityVector3());
                            }
                            currentControlPoint = _handler.ControlPoints.Find(cp => cp.WorldPos == v.ToUnityVector3());
                        }
                        if (currentControlPoint != null)
                        {
                            controlPointsSegments[currentControlPoint.Index].Add(v.ToUnityVector3());
                        }
                    }

                    // close loop if needed
                    if (_handler.DragPointInspector.PointsAreLooping)
                    {
                        controlPointsSegments[_handler.ControlPoints.Count - 1].Add(controlPointsSegments[0][0]);
                    }

                    // construct full path
                    _pathPoints.Clear();
                    const float splitRatio = 0.1f;
                    foreach (var controlPoint in _handler.ControlPoints)
                    {
                        // Split straight segments to avoid HandleUtility.ClosestPointToPolyLine issues
                        ref var segments = ref controlPointsSegments[controlPoint.Index];
                        if (segments.Count == 2)
                        {
                            var dir  = segments[1] - segments[0];
                            var dist = dir.magnitude;
                            dir = Vector3.Normalize(dir);
                            var newPath = new List <Vector3> {
                                segments[0]
                            };
                            for (var splitDist = dist * splitRatio; splitDist < dist; splitDist += dist * splitRatio)
                            {
                                newPath.Add(newPath[0] + dir * splitDist);
                            }
                            newPath.Add(segments[1]);
                            segments = newPath;
                        }
                        _pathPoints.AddRange(segments);
                    }

                    _curveTravellerMoved = false;
                    if (_pathPoints.Count > 1)
                    {
                        var newPos = HandleUtility.ClosestPointToPolyLine(_pathPoints.ToArray());
                        if ((newPos - _handler.CurveTravellerPosition).magnitude >= HandleUtility.GetHandleSize(_handler.CurveTravellerPosition) * ControlPoint.ScreenRadius * CurveTravellerSizeRatio * 0.1f)
                        {
                            _handler.CurveTravellerPosition = newPos;
                            _curveTravellerMoved            = true;
                        }
                    }

                    // Render Curve with correct color regarding drag point properties & find curve section where the curve traveller is
                    _handler.CurveTravellerControlPointIdx = -1;
                    var minDist = float.MaxValue;
                    foreach (var controlPoint in _handler.ControlPoints)
                    {
                        var segments = controlPointsSegments[controlPoint.Index].ToArray();
                        if (segments.Length > 1)
                        {
                            Handles.color = _handler.DragPointInspector.DragPointExposition.Contains(DragPointExposure.SlingShot) && controlPoint.DragPoint.IsSlingshot ? CurveSlingShotColor : CurveColor;
                            Handles.DrawAAPolyLine(CurveWidth, segments);
                            var closestToPath = HandleUtility.ClosestPointToPolyLine(segments);
                            var dist          = (closestToPath - _handler.CurveTravellerPosition).magnitude;
                            if (dist < minDist)
                            {
                                minDist = dist;
                                _handler.CurveTravellerControlPointIdx = controlPoint.Index;
                            }
                        }
                    }
                }
            }
示例#9
0
    void OnSceneGUI()
    {
        EventType evt = Event.current.type;

        SkinMaker skin = (SkinMaker)target;

        List <Vector3> ctlp = skin.controlPoints.Select(v => v + skin.transform.position).ToList();

        ctlp.Add(skin.controlPoints[0] + skin.transform.position);
        Vector3[] poly = ctlp.ToArray();

        Handles.color = Color.gray;
        Handles.DrawAAPolyLine(poly);

        Vector3 p       = HandleUtility.ClosestPointToPolyLine(poly);
        int     selCtrl = -1;

        Handles.color = Color.green;

        for (int i = 0; i < skin.controlPoints.Length; i++)
        {
            Vector3 hp = Handles.FreeMoveHandle(skin.transform.position + skin.controlPoints[i], Quaternion.identity, 0.05f, Vector3.zero, Handles.RectangleCap);
            if (Vector3.Distance(hp, p) < 0.05f)
            {
                selCtrl = i;
            }
            hp = hp - skin.transform.position;
            skin.controlPoints[i] = new Vector3(Mathf.Clamp(hp.x, -1, 1), Mathf.Clamp(hp.y, -1, 1), Mathf.Clamp(hp.z, -1, 1));
        }

        if (Event.current.shift)
        {
            Handles.color = Color.blue;
            Handles.DrawWireDisc(p, Vector3.forward, 0.05f);

            if (evt == EventType.mouseDown)
            {
                Undo.RecordObject(skin, "Add handle");
                for (int i = 0; i < poly.Length - 1; i++)
                {
                    float d = (float)System.Math.Round(HandleUtility.DistancePointLine(p, ctlp[i], ctlp[i + 1]), 4);
                    if (d == 0)
                    {
                        ctlp = new List <Vector3>(skin.controlPoints);
                        ctlp.Insert(i + 1, p - skin.transform.position);
                        skin.controlPoints = ctlp.ToArray();
                    }
                }
            }
        }
        else if (Event.current.control)
        {
            if (evt == EventType.mouseDown)
            {
                Undo.RecordObject(skin, "Remove handle");
                if (selCtrl != -1)
                {
                    if (skin.controlPoints.Length > 4)
                    {
                        ctlp = new List <Vector3>(skin.controlPoints);
                        ctlp.RemoveAt(selCtrl);
                        skin.controlPoints = ctlp.ToArray();
                    }
                    else
                    {
                        EditorUtility.DisplayDialog("Cannot delete control point", "There have to be at least 4 control points.", "Ok");
                    }
                }
            }
        }
    }
示例#10
0
        private void DisplayCollider()
        {
            Event e = Event.current;

            if (tileSet.selected_tileSetBrushId != TileSetConst.TileSetBrushId_Default)
            {
                EditorGUILayout.LabelField("tileSetBrush不能被编辑", EditorStyles.boldLabel);
                return;
            }

            bool is_multi_selection = tileSet.tileSelection != null;
            bool is_save_changes    = false;
            Tile selected_tile      = is_multi_selection
      ? tileSet.tile_list[TileSetUtil.GetTileIdFromTileData(tileSet.tileSelection.selection_tileData_list[0])]
      : tileSet.selected_tile;

            if (e.type == EventType.MouseDown)
            {
                is_dragging = true;
                if (selected_tile.tileColliderData.vertices != null)
                {
                    saved_vertexs = new Vector2[selected_tile.tileColliderData.vertices.Length];
                    selected_tile.tileColliderData.vertices.CopyTo(saved_vertexs, 0);
                }
            }
            else if (e.type == EventType.MouseUp)
            {
                is_dragging = false;
            }

            //background_color
            tileSet.background_color = EditorGUILayout.ColorField(tileSet.background_color);
            if (pre_background_color != tileSet.background_color || GUIStyleConst.Scroll_Style.normal.background == null)
            {
                pre_background_color = tileSet.background_color;
                if (GUIStyleConst.Scroll_Style.normal.background == null)
                {
                    GUIStyleConst.Scroll_Style.normal.background = new Texture2D(1, 1)
                    {
                        hideFlags = HideFlags.DontSave
                    }
                }
                ;
                GUIStyleConst.Scroll_Style.normal.background.SetPixel(0, 0, tileSet.background_color);
                GUIStyleConst.Scroll_Style.normal.background.Apply();
            }

            float aspect_ratio = tileSet.tile_pixel_size.x / tileSet.tile_pixel_size.y; //比例
            float padding      = 2;                                                     // pixel size of the border around the tile

            //画tile图
            //包围tile_rect的rect
            Rect tile_parent_rect = GUILayoutUtility.GetRect(1, 1, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));

            using (new GUIBeginGroupScope(tile_parent_rect, GUIStyleConst.Scroll_Style))
            {
                if (e.type == EventType.Repaint)
                {
                    float tile_pixel_size = tile_parent_rect.width / (tileSet.tile_pixel_size.x + 2 * padding);//2*padding是因为padding有左边和右边
                    mouse_pos = e.mousePosition;
                    tile_rect = new Rect(padding * tile_pixel_size, padding * tile_pixel_size,
                                         tile_parent_rect.width - 2 * padding * tile_pixel_size,
                                         (tile_parent_rect.width / aspect_ratio) - 2 * padding * tile_pixel_size);
                    tile_rect.height = Mathf.Min(tile_rect.height, tile_parent_rect.height - 2 * padding * tile_pixel_size);
                    tile_rect.width  = (tile_rect.height * aspect_ratio);
                }
                using (new GUIColorScope(new Color(1f, 1f, 1f, 0.1f)))
                {
                    GUI.DrawTexture(tile_rect, EditorGUIUtility.whiteTexture);
                }
                if (is_multi_selection)
                {
                    foreach (uint tileData in tileSet.tileSelection.selection_tileData_list)
                    {
                        int  tileId = TileSetUtil.GetTileIdFromTileData(tileData);
                        Tile tile   = tileSet.GetTile(tileId);
                        if (tile != null)
                        {
                            GUI.color = new Color(1f, 1f, 1f, 1f / tileSet.tileSelection.selection_tileData_list.Count);
                            GUI.DrawTextureWithTexCoords(tile_rect, tileSet.atlas_texture, tile.uv);
                        }
                    }
                    GUI.color = Color.white;
                }
                else
                {
                    GUI.DrawTextureWithTexCoords(tile_rect, tileSet.atlas_texture, selected_tile.uv);
                }

                /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                Color saved_handle_color = Handles.color;
                if (selected_tile.tileColliderData.type != TileColliderType.None)
                {
                    Vector2[] collider_vertices = selected_tile.tileColliderData.type == TileColliderType.Full ? TileConst.Full_Collider_Tile_Vertices : selected_tile.tileColliderData.vertices;
                    if (collider_vertices == null || collider_vertices.Length == 0)
                    {
                        collider_vertices = selected_tile.tileColliderData.vertices = new Vector2[TileConst.Full_Collider_Tile_Vertices.Length];
                        Array.Copy(TileConst.Full_Collider_Tile_Vertices, collider_vertices, TileConst.Full_Collider_Tile_Vertices.Length);
                        EditorUtility.SetDirty(tileSet);
                    }

                    // 将vertice的xy限制在[0,1]之间
                    for (int i = 0; i < collider_vertices.Length; ++i)
                    {
                        Vector2 collider_vertice = collider_vertices[i];
                        collider_vertice     = collider_vertice.Snap2(tileSet.tile_pixel_size).ConvertElement(v => Mathf.Clamp01(v));
                        collider_vertices[i] = collider_vertice;
                    }

                    // 画边 draw edges
                    Vector3[] poly_edges = new Vector3[collider_vertices.Length + 1];
                    for (int i = 0; i < collider_vertices.Length; ++i)
                    {
                        Vector2 collider_vertice = collider_vertices[i];
                        collider_vertice.x = tile_rect.x + tile_rect.width * collider_vertice.x;
                        collider_vertice.y = tile_rect.yMax - tile_rect.height * collider_vertice.y;

                        Vector2 collider_vertice_next = collider_vertices[(i + 1) % collider_vertices.Length];
                        collider_vertice_next.x = tile_rect.x + tile_rect.width * collider_vertice_next.x;
                        collider_vertice_next.y = tile_rect.yMax - tile_rect.height * collider_vertice_next.y;

                        poly_edges[i]     = collider_vertice;
                        poly_edges[i + 1] = collider_vertice_next;

                        //画边
                        Handles.color = Color.green;
                        Handles.DrawLine(collider_vertice, collider_vertice_next);
                        //画边上的法线 Draw normals
                        Handles.color = Color.white;
                        Vector3 normal_pos = (collider_vertice + collider_vertice_next) / 2f;
                        Handles.DrawLine(normal_pos, normal_pos + Vector3.Cross(collider_vertice_next - collider_vertice, Vector3.forward).normalized *tile_rect.yMin);

                        Handles.color = saved_handle_color;
                    }

                    float pixel_size = tile_rect.width / tileSet.tile_pixel_size.x;
                    if (selected_tile.tileColliderData.type == TileColliderType.Polygon)
                    {
                        bool is_adding_vertex_on   = !is_dragging && e.shift && active_vertex_index == -1;
                        bool is_removing_vertex_on = !is_dragging && ((Application.platform == RuntimePlatform.OSXEditor) ? e.command : e.control) && collider_vertices.Length > 3;
                        //删除顶点
                        if (is_removing_vertex_on && active_vertex_index != -1 && e.type == EventType.MouseUp)
                        {
                            selected_tile.tileColliderData.vertices = new Vector2[collider_vertices.Length - 1];
                            for (int i = 0, j = 0; i < collider_vertices.Length; ++i)
                            {
                                if (i == active_vertex_index)
                                {
                                    continue;
                                }
                                selected_tile.tileColliderData.vertices[j] = collider_vertices[i];
                                ++j;
                            }
                            collider_vertices   = selected_tile.tileColliderData.vertices;
                            active_vertex_index = -1;
                        }

                        float min_distance = float.MaxValue;
                        if (!is_dragging)
                        {
                            active_vertex_index = -1;
                        }
                        for (int i = 0; i < collider_vertices.Length; ++i)
                        {
                            Vector2 collider_vertice = collider_vertices[i];
                            collider_vertice.x = tile_rect.x + tile_rect.width * collider_vertice.x;
                            collider_vertice.y = tile_rect.yMax - tile_rect.height * collider_vertice.y;

                            if (is_dragging)
                            {
                                if (i == active_vertex_index)
                                {
                                    collider_vertice       = mouse_pos;
                                    collider_vertice      -= tile_rect.position;
                                    collider_vertice.x     = Mathf.Clamp(Mathf.Round(collider_vertice.x / pixel_size) * pixel_size, 0, tile_rect.width);
                                    collider_vertice.y     = Mathf.Clamp(Mathf.Round(collider_vertice.y / pixel_size) * pixel_size, 0, tile_rect.height);
                                    collider_vertice      += tile_rect.position;
                                    collider_vertices[i].x = Mathf.Clamp01((collider_vertice.x - tile_rect.x) / tile_rect.width);
                                    collider_vertices[i].y = Mathf.Clamp01((collider_vertice.y - tile_rect.yMax) / -tile_rect.height);
                                }
                            }
                            else
                            {
                                float distance = Vector2.Distance(mouse_pos, collider_vertice);
                                //distance < GUIStyleConst.Collider_Vertex_Handle_Style.normal.background.width是为了限定少于多少距离(该顶点与mouse_pos的距离)的时候才选中该顶点
                                if (distance <= min_distance && distance < GUIStyleConst.Collider_Vertex_Handle_Style.normal.background.width)
                                {
                                    min_distance        = distance;
                                    active_vertex_index = i;
                                }
                            }
                            //画顶点
                            if (e.type == EventType.Repaint)
                            {
                                //画左上角的坐标
                                if (i == active_vertex_index)
                                {
                                    GUIStyleConst.VertexCoord_Style.fontSize = (int)(Mathf.Min(12f, tile_rect.yMin / 2f));
                                    GUI.Label(new Rect(0, 0, tile_rect.width, tile_rect.yMin), Vector2.Scale(collider_vertices[i], tileSet.tile_pixel_size).ToString(), GUIStyleConst.VertexCoord_Style);
                                }
                                GUI.color = active_vertex_index == i ? (is_removing_vertex_on ? Color.red : Color.cyan) : new Color(0.7f, 0.7f, 0.7f, 0.8f);
                                GUIStyleConst.Collider_Vertex_Handle_Style.Draw(new Rect(collider_vertice.x - GUIStyleConst.Collider_Vertex_Handle_Style.normal.background.width / 2, collider_vertice.y - GUIStyleConst.Collider_Vertex_Handle_Style.normal.background.height / 2, 1, 1), i.ToString(), false, false, false, false);
                                GUI.color = Color.white;
                            }
                        }

                        //添加顶点
                        if (is_adding_vertex_on)
                        {
                            //线段index
                            int     segment_index;
                            Vector2 new_vertex_pos = ClosestPointToPolyLine(poly_edges, out segment_index);

                            if (e.type == EventType.MouseUp)
                            {
                                selected_tile.tileColliderData.vertices = new Vector2[collider_vertices.Length + 1];
                                segment_index = (segment_index + 1) % selected_tile.tileColliderData.vertices.Length;
                                for (int i = 0, j = 0; i < selected_tile.tileColliderData.vertices.Length; ++i)
                                {
                                    if (segment_index == i)
                                    {
                                        new_vertex_pos.x = Mathf.Clamp(Mathf.Round(new_vertex_pos.x / pixel_size) * pixel_size, tile_rect.x, tile_rect.xMax);
                                        new_vertex_pos.y = Mathf.Clamp(Mathf.Round(new_vertex_pos.y / pixel_size) * pixel_size, tile_rect.y, tile_rect.yMax);
                                        selected_tile.tileColliderData.vertices[i].x = Mathf.Clamp01((new_vertex_pos.x - tile_rect.x) / tile_rect.width);
                                        selected_tile.tileColliderData.vertices[i].y = Mathf.Clamp01((new_vertex_pos.y - tile_rect.yMax) / -tile_rect.height);
                                    }
                                    else
                                    {
                                        selected_tile.tileColliderData.vertices[i] = collider_vertices[j];
                                        ++j;
                                    }
                                }
                                collider_vertices   = selected_tile.tileColliderData.vertices;
                                active_vertex_index = -1;
                            }
                            else if (e.type == EventType.Repaint)
                            {
                                //添加顶点中移动鼠标,透明动态显示当前将要新增顶点的位置
                                GUI.color = new Color(0.7f, 0.7f, 0.7f, 0.8f);
                                GUIStyleConst.Collider_Vertex_Handle_Style.Draw(new Rect(new_vertex_pos.x - GUIStyleConst.Collider_Vertex_Handle_Style.normal.background.width / 2, new_vertex_pos.y - GUIStyleConst.Collider_Vertex_Handle_Style.normal.background.height / 2, 1, 1), segment_index.ToString(), false, false, false, false);
                                GUI.color = Color.white;
                            }
                        }
                    }

                    if (e.type == EventType.MouseUp)
                    {
                        is_save_changes = true;
                        //remove duplicated vertex
                        selected_tile.tileColliderData.vertices = selected_tile.tileColliderData.vertices.Distinct().ToArray();
                        if (selected_tile.tileColliderData.vertices.Length <= 2)
                        {
                            selected_tile.tileColliderData.vertices = saved_vertexs;
                        }
                        //snap vertex positions
                        selected_tile.tileColliderData.SnapVertices(tileSet);
                    }
                }
            }



            if (GUILayout.Button("反转法线"))
            {
                selected_tile.tileColliderData.vertices.Reverse();
            }

            EditorGUILayout.Space();

            string helpInfo =
                "  - 移动:点击图中的顶点并移动它的位置" + "\n" +
                "  - 添加:按住Shift并点击鼠标进行添加顶点" + "\n" +
                "  - 删除:按住Ctrl并且点击顶点进行删除顶点 (should be more than 3)";

            EditorGUILayout.HelpBox(helpInfo, MessageType.Info);

            // Collider Settings
            float saved_label_width = EditorGUIUtility.labelWidth;

            EditorGUIUtility.labelWidth = 40;
            if (is_multi_selection)
            {
                EditorGUILayout.LabelField("* Multi-selection Edition", EditorStyles.boldLabel);
            }
            using (new EditorGUILayoutBeginHorizontalScope(GUILayout.MinWidth(140)))
            {
                EditorGUILayout.LabelField("Collider Data", EditorStyles.boldLabel);
                if (GUILayout.Button("Copy", GUILayout.Width(50)))
                {
                    copied_colliderData = selected_tile.tileColliderData.Clone();
                }
                if (GUILayout.Button("Paste", GUILayout.Width(50)))
                {
                    selected_tile.tileColliderData = copied_colliderData.Clone();
                    is_save_changes = true;
                }
            }
            EditorGUILayout.Space();

            using (var check = new EditorGUIBeginChangeCheckScope())
            {
                EditorGUIUtility.labelWidth = 100;
                EditorGUILayout.LabelField("Collider Type:", EditorStyles.boldLabel);
                using (new EditorGUIIndentLevelScope(2))
                {
                    string[] tile_collider_names = Enum.GetNames(typeof(TileColliderType));
                    selected_tile.tileColliderData.type = (TileColliderType)GUILayout.Toolbar((int)selected_tile.tileColliderData.type, tile_collider_names);
                }
                EditorGUIUtility.labelWidth = saved_label_width;
                is_save_changes            |= check.IsChanged;
            }

            //Save changes
            if (is_save_changes)
            {
                if (is_multi_selection)
                {
                    for (int i = 0; i < tileSet.tileSelection.selection_tileData_list.Count; ++i)
                    {
                        tileSet.tile_list[TileSetUtil.GetTileIdFromTileData(tileSet.tileSelection.selection_tileData_list[i])].tileColliderData = selected_tile.tileColliderData.Clone();
                    }
                }
                EditorUtility.SetDirty(tileSet);
                //Refresh selected tileMap
                TileMap selected_tileMap = Selection.activeGameObject ? Selection.activeGameObject.GetComponent <TileMap>() : null;
                if (selected_tileMap)
                {
                    selected_tileMap.Refresh(false, true);
                }
            }
        }

        //获取polyline(vertices组成的线段)线段上的离当前mouse poistion最近的点
        //Get the point on a polyline (in 3D space) which is closest to the current mouse position
        Vector3 ClosestPointToPolyLine(Vector3[] vertices, out int closest_segment_index)
        {
            float min_distance = float.MaxValue;

            closest_segment_index = 0;
            for (int i = 0; i < vertices.Length - 1; ++i)
            {
                float distance = HandleUtility.DistanceToLine(vertices[i], vertices[i + 1]);
                if (distance < min_distance)
                {
                    min_distance          = distance;
                    closest_segment_index = i;
                }
            }
            return(HandleUtility.ClosestPointToPolyLine(vertices));
        }
    }
示例#11
0
        void OnSceneGUI()
        {
            Shape shape = (Shape)target;

            if (!isEditingPolygon || shape.settings.shapeType != ShapeType.Polygon)
            {
                return;
            }
            // all the rest is for polygon editing
            if (Tools.current != Tool.None)
            {
                StopEditingPolygon(false);
                return;
            }
            HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));
            // draw the borders so the user knows where vertices should live
            DrawShapeBorders(shape);
            // get the existing verts
            Vector3[]      oldVerts    = shape.GetPolygonWorldVertices();
            List <Vector3> verts       = new List <Vector3>(oldVerts);
            bool           hasMaxVerts = verts.Count == Shape.MaxPolygonVertices;

            // add the first vert at the end as well so Unity will draw it right etc
            verts.Add(verts[0]);
            // are we in delete mode?  what color should handles be?
            Color pink       = new Color(1, 0, 0.75f);
            bool  deleteMode = false;

            if ((Event.current.control || Event.current.command) && verts.Count > 4)
            {
                Handles.color = Color.red;
                deleteMode    = true;
            }
            else
            {
                Handles.color = pink;
            }
            // draw the shape
            Handles.DrawAAPolyLine(3f, verts.ToArray());
            // drag handle result for getting info from our handles
            CustomHandles.DragHandleResult dhResult;
            // draw handles for each existing vert and check if they've been moved or clicked
            bool changed = false;

            for (int i = verts.Count - 2; i >= 0; i--)
            {
                Vector3 v      = verts[i];
                Vector3 newPos = CustomHandles.DragHandle(v, 0.05f * HandleUtility.GetHandleSize(v),
                                                          Handles.DotCap, pink, out dhResult);
                if (deleteMode && dhResult == CustomHandles.DragHandleResult.LMBPress)
                {
                    // the user clicked on the handle while in delete mode, so delete the vert
                    verts.RemoveAt(i);
                    changed = true;
                }
                else if (!deleteMode && newPos != v)
                {
                    // the handle has been dragged, so move the vert to the new position
                    verts[i] = new Vector2(newPos.x, newPos.y);
                    changed  = true;
                }
            }
            // check if the mouse is hovering over a space where we could add a new vert,
            // and draw it if so
            bool    snapped       = false;
            Vector3 closestPos    = HandleUtility.ClosestPointToPolyLine(verts.ToArray());
            float   distance      = HandleUtility.DistanceToPolyLine(verts.ToArray());
            bool    isCloseToLine = distance < 25;

            if (!changed && isCloseToLine && !hasMaxVerts && !deleteMode)
            {
                // todo - ClosestPointToPolyLine doesn't work very well in 3D...
                foreach (Vector3 v in verts)
                {
                    // if close to an existing vert, we don't want to add a new one
                    if (Vector2.Distance(HandleUtility.WorldToGUIPoint(closestPos),
                                         HandleUtility.WorldToGUIPoint(v)) < 15)
                    {
                        snapped = true;
                        break;
                    }
                }
                if (!snapped)
                {
                    // not too close to an existing vert, so draw a new one.  don't
                    // use an actual handle cause we want to intercept nearby clicks
                    // and not just clicks directly on the handle.
                    Rect  rect = new Rect();
                    float dim  = 0.05f * HandleUtility.GetHandleSize(closestPos);
                    rect.center   = closestPos - new Vector3(dim, dim, 0);
                    rect.size     = new Vector2(dim * 2, dim * 2);
                    Handles.color = Color.white; // remove the weird tint it does
                    Handles.DrawSolidRectangleWithOutline(rect, Color.green, Color.clear);
                    if (Event.current.type == EventType.MouseDown)
                    {
                        // the user has clicked the new vert, so add it for real
                        // figure out which line segment it's on
                        int lineStart = GetClosestLineToPoint(closestPos, verts);
                        verts.Insert(lineStart + 1, closestPos);
                        changed = true;
                    }
                }
            }
            // something has been changed, so apply the new verts back to the shape
            if (changed)
            {
                // make sure to remove the duplicated last vert we added
                Undo.RecordObject(shape, "Edit Shapes2D Polygon Vertices");
                shape.SetPolygonWorldVertices(
                    verts.GetRange(0, verts.Count - 1).ToArray());
                EditorUtility.SetDirty(target);
            }
            else
            {
                HandleUtility.Repaint(); // to draw the new vert placeholder handle
                if (Event.current.type == EventType.MouseDown && !isCloseToLine)
                {
                    StopEditingPolygon(true);
                }
            }
        }
    void OnSceneGUI()
    {
        //Tools.current = Tool.None;
        Event m_Event = Event.current;

        if (_editor.now_option == 1)
        {
            #region [시작시 점 위치]
            if (_editor.awake)
            {
                _editor.awake       = false;
                _editor.waypoint[0] = _editor.transform.position;
                _editor.waypoint[1] = _editor.transform.position + new Vector3(1, 0, 0);
                _editor.waypoint[2] = _editor.transform.position + new Vector3(0.5f, 1, 0);
                _editor.start_pos   = _editor.waypoint[0];
            }
            else
            {
                _editor.transform.position = _editor.start_pos;
            }
            #endregion

            #region [점에 핸들달기]
            for (int i = 0; i < _editor.waypoint.Count; i++)
            {
                _editor.waypoint[i] = Handles.FreeMoveHandle(_editor.waypoint[i], Quaternion.identity, 0.05f, new Vector3(10, 10, 10), Handles.RectangleHandleCap);
            }
            #endregion

            #region [폴리곤 테두리 표시]
            Handles.color = Color.cyan;
            Vector3[] MouseLineVector;
            if (_editor.route_rotation)
            {
                MouseLineVector = new Vector3[_editor.waypoint.Count + 1];
                for (int j = 0; j < _editor.waypoint.Count; j++)
                {
                    MouseLineVector[j] = _editor.waypoint[j];
                }
                MouseLineVector[_editor.waypoint.Count] = _editor.waypoint[0];
            }
            else
            {
                MouseLineVector = new Vector3[_editor.waypoint.Count];
                for (int j = 0; j < _editor.waypoint.Count; j++)
                {
                    MouseLineVector[j] = _editor.waypoint[j];
                }
            }
            Vector3 closestPoint = HandleUtility.ClosestPointToPolyLine(MouseLineVector);
            //Handles.DotHandleCap(0, closestPoint, Quaternion.identity, 0.05f, EventType.Repaint);
            #endregion

            #region [점 추가]
            if (m_Event.type == EventType.MouseDown && m_Event.button == 0)
            {
                //if(Vector3.Distance(Camera.main.ScreenToWorldPoint(new Vector3(m_Event.mousePosition.x, m_Event.mousePosition.y, -Camera.main.transform.position.z)),closestPoint) < 2f)
                // {
                Vector3 start = _editor.waypoint[0];
                Vector3 end   = _editor.waypoint[1];
                float   dis   = HandleUtility.DistancePointLine(closestPoint, start, end);
                int     num   = 1;
                for (int i = 1; i < _editor.waypoint.Count; i++)
                {
                    float distance = HandleUtility.DistancePointLine(closestPoint, _editor.waypoint[i - 1], _editor.waypoint[i]);
                    if (distance < dis)
                    {
                        num = i;
                        dis = distance;
                    }
                }
                if (_editor.route_rotation)
                {
                    float distance = HandleUtility.DistancePointLine(closestPoint, _editor.waypoint[_editor.waypoint.Count - 1], _editor.waypoint[0]);
                    if (distance < dis)
                    {
                        num = _editor.waypoint.Count;
                    }
                }
                _editor.waypoint.Insert(num, closestPoint);
                // }
            }
            #endregion
        }
    }
示例#13
0
    public static void Node_Add(SPData sPData)
    {
        SceneView.currentDrawingSceneView.Repaint();
        EditorGUIUtility.AddCursorRect(Camera.current.pixelRect, MouseCursor.ArrowPlus);

        int     nIndex        = 0;
        string  vertexPostion = "init";
        Vector3 vert          = Vector3.zero;

        if (sPData.Nodes.Count >= 2)
        {
            vert = HandleUtility.ClosestPointToPolyLine(sPData.Vertices.ToArray());

            if (sPData.Close)
            {
                nIndex        = BranchClosestNodeToVertex(sPData, vert);
                vertexPostion = "mid";
            }
            else
            {
                if (Vector3.Distance(sPData.FirstNode.Point.position, vert) <= float.Epsilon)
                {
                    nIndex        = 0;
                    vertexPostion = "beg";
                }

                else if (Vector3.Distance(sPData.LastNode.Point.position, vert) <= float.Epsilon)
                {
                    nIndex        = sPData.Nodes.Count - 1;
                    vertexPostion = "end";
                }
                else
                {
                    nIndex        = BranchClosestNodeToVertex(sPData, vert);
                    vertexPostion = "mid";
                }
            }
        }



        // convert mouse position to vector3 world space
        Func <Vector2, Vector3> MousePos_To_Vector3 = delegate(Vector2 mousePosition)
        {
            float      distance = 0.0f;
            RaycastHit Hit;
            Ray        ray = new Ray();
            Plane      m_Plane;
            Vector3    hitPoint = Vector3.zero;

            ray = HandleUtility.GUIPointToWorldRay(mousePosition);

            if (Camera.current.transform.eulerAngles == new Vector3(0, 0, 0) || Camera.current.transform.eulerAngles == new Vector3(0, 180, 0))
            {
                m_Plane = new Plane(Vector3.forward, Vector3.zero);
            }
            else if (Camera.current.transform.eulerAngles == new Vector3(90, 0, 0) || Camera.current.transform.eulerAngles == new Vector3(270, 0, 0))
            {
                m_Plane = new Plane(Vector3.up, Vector3.zero);
            }
            else if (Camera.current.transform.eulerAngles == new Vector3(0, 90, 0) || Camera.current.transform.eulerAngles == new Vector3(0, 270, 0))
            {
                m_Plane = new Plane(Vector3.right, Vector3.zero);
            }
            else
            {
                m_Plane = new Plane(Vector3.up, Vector3.zero);
            }

            if (Physics.Raycast(ray, out Hit))
            {
                hitPoint = Hit.point;
            }
            else if (m_Plane.Raycast(ray, out distance))
            {
                hitPoint = ray.GetPoint(distance);
            }

            return(hitPoint);
        };

        // Add node to branch when click is performed
        Action <Vector3> Add_Node_Click = delegate(Vector3 pos)
        {
            if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
            {
                Undo.RecordObject(sPData.SplinePlus, "Node added");
                Func <string, Vector3, Quaternion, Transform, Transform> CreatePoint = delegate(string name, Vector3 Pos, Quaternion Rot, Transform Parent)
                {
                    var Obj = new GameObject(name);
                    Obj.hideFlags          = HideFlags.HideInHierarchy;
                    Obj.transform.position = Pos;
                    Obj.transform.rotation = Rot;
                    Obj.transform.parent   = Parent;
                    return(Obj.transform);
                };

                var node = new Node();

                node._Type = sPData.SplineSettings.NodeType;

                node.Point  = CreatePoint("p", pos, Quaternion.identity, sPData.SplinePlus.gameObject.transform);
                node.Point1 = CreatePoint("p1", node.Point.position, Quaternion.identity, node.Point);
                node.Point2 = CreatePoint("p2", node.Point.position, Quaternion.identity, node.Point);

                if (sPData.Close)
                {
                    SplinePlusAPI.Add_Node_At_Index(sPData, node, nIndex + 1);
                }
                else
                {
                    if (vertexPostion == "beg" || vertexPostion == "init")
                    {
                        SplinePlusAPI.Add_Node_Beginning(sPData, node);
                    }
                    else if (vertexPostion == "end")
                    {
                        SplinePlusAPI.Add_Node_End(sPData, node);
                    }
                    else
                    {
                        SplinePlusAPI.Add_Node_At_Index(sPData, node, nIndex + 1);
                    }
                }
            }
        };

        //perform node adding when click event happens
        if (vertexPostion == "init")
        {
            var hitPoint = MousePos_To_Vector3(Event.current.mousePosition);
            Handles.color = Color.yellow;
            Handles.SphereHandleCap(0, hitPoint, Quaternion.identity, sPData.SplineSettings.GizmosSize * 2, EventType.Repaint);

            Add_Node_Click(hitPoint);
        }
        // node added to the beginning of the branch
        else if (vertexPostion == "beg")
        {
            var pos  = MousePos_To_Vector3(Event.current.mousePosition);
            var node = sPData.Nodes[0];

            Preview(sPData, node.Point.position, pos);
            Add_Node_Click(pos);
        }
        // node added to the end of the branch
        else if (vertexPostion == "end")
        {
            var pos  = MousePos_To_Vector3(Event.current.mousePosition);
            var node = sPData.Nodes[sPData.Nodes.Count - 1];

            Preview(sPData, node.Point.position, pos);
            Add_Node_Click(pos);
        }
        // node added in the middle of the branch
        else
        {
            Handles.color = Color.yellow;
            Handles.SphereHandleCap(0, vert, Quaternion.identity, sPData.SplineSettings.GizmosSize * 2, EventType.Repaint);

            Add_Node_Click(vert);
        }
    }
示例#14
0
    void OnSceneGUI()
    {
        // Tools.current = Tool.None;
        Event m_Event = Event.current;

        #region [시작시 점 위치]
        if (_editor.awake)
        {
            _editor.awake         = false;
            _editor.camera_pos[0] = _editor.transform.position + new Vector3(+1, +1, 0);
            _editor.camera_pos[1] = _editor.transform.position + new Vector3(1, -1, 0);
            _editor.camera_pos[2] = _editor.transform.position + new Vector3(-1, -1, 0);
            _editor.camera_pos[3] = _editor.transform.position + new Vector3(-1, +1, 0);
        }
        #endregion

        #region [점에 핸들달기]
        for (int i = 0; i < _editor.camera_pos.Count; i++)
        {
            _editor.camera_pos[i] = Handles.FreeMoveHandle(_editor.camera_pos[i], Quaternion.identity, 0.05f, new Vector3(10, 10, 10), Handles.RectangleHandleCap);
        }
        #endregion

        #region [폴리곤 테두리 표시]
        Handles.color = Color.cyan;
        Vector3[] MouseLineVector;
        MouseLineVector = new Vector3[_editor.camera_pos.Count + 1];
        for (int j = 0; j < _editor.camera_pos.Count; j++)
        {
            MouseLineVector[j] = _editor.camera_pos[j];
        }
        MouseLineVector[_editor.camera_pos.Count] = _editor.camera_pos[0];
        Vector3 closestPoint = HandleUtility.ClosestPointToPolyLine(MouseLineVector);
        #endregion

        #region [점 추가]
        if (m_Event.type == EventType.MouseDown && m_Event.button == 0)
        {
            Vector3 start    = _editor.camera_pos[0];
            Vector3 end      = _editor.camera_pos[1];
            float   dis      = HandleUtility.DistancePointLine(closestPoint, start, end);
            int     num      = 1;
            float   distance = 0;
            for (int i = 1; i < _editor.camera_pos.Count; i++)
            {
                distance = HandleUtility.DistancePointLine(closestPoint, _editor.camera_pos[i - 1], _editor.camera_pos[i]);
                if (distance < dis)
                {
                    num = i;
                    dis = distance;
                }
            }
            distance = HandleUtility.DistancePointLine(closestPoint, _editor.camera_pos[_editor.camera_pos.Count - 1], _editor.camera_pos[0]);
            if (distance < dis)
            {
                num = _editor.camera_pos.Count;
            }
            _editor.camera_pos.Insert(num, closestPoint);
        }
        #endregion
    }