private void OnSceneGUI()

in SupportingScripts/Editor/Scripts/MapPinEditor.cs [65:185]


        private void OnSceneGUI()
        {
            // If childed to a MapRenderer, don't use the default tools. Use a tool that can update the MapPin's location.
            var mapPin = (MapPin)target;
            var mapRenderer = mapPin.transform.parent?.GetComponent<MapRenderer>();
            if (mapRenderer != null)
            {
                var transform = mapPin.transform;

                Tools.hidden = true;

                var controlId = GUIUtility.GetControlID("MapPinEditorHandle".GetHashCode(), FocusType.Passive);
                var size = 0.025f;

                switch (Event.current.GetTypeForControl(controlId))
                {
                    case EventType.Layout:
                        Handles.RectangleHandleCap(
                            controlId,
                            _isDragging ? new Vector3(transform.position.x, (float)_mouseDownMapPinPositionInMercatorSpace.Y, transform.position.z) : transform.position,
                            transform.rotation * Quaternion.LookRotation(Vector3.up),
                            size,
                            EventType.Layout);
                        break;
                    case EventType.MouseMove:
                        if (HandleUtility.nearestControl == controlId)
                        {
                            _isHovered = true;
                            Event.current.Use();
                        }
                        else
                        {
                            _isHovered = false;
                        }
                        break;
                    case EventType.MouseDown:
                        if (HandleUtility.nearestControl == controlId)
                        {
                            var ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                            var plane = new Plane(transform.up, transform.position);
                            if (plane.Raycast(ray, out var enter))
                            {
                                // Respond to a press on this handle. Drag starts automatically.
                                _mouseDownMapPinPlanePositionInMapLocalSpace = mapRenderer.transform.worldToLocalMatrix * ray.GetPoint(enter);
                                _mouseDownMapPinPositionInMercatorSpace = mapPin.Location.ToMercatorCoordinate();
                                _isDragging = true;
                                GUIUtility.hotControl = controlId;
                                Event.current.Use();
                            }
                        }
                        break;
                    case EventType.MouseUp:
                        if (GUIUtility.hotControl == controlId)
                        {
                            // Respond to a release on this handle. Drag stops automatically.
                            _isDragging = false;
                            GUIUtility.hotControl = 0;
                            Event.current.Use();
                        }
                        break;

                    case EventType.MouseDrag:
                        if (_isDragging)
                        {
                            var ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                            var plane = new Plane(transform.up, _mouseDownMapPinPlanePositionInMapLocalSpace);
                            if (plane.Raycast(ray, out var enter))
                            {
                                Vector3 updatedHitPointInLocalSpace = mapRenderer.transform.worldToLocalMatrix * ray.GetPoint(enter);
                                var newDeltaInLocalSpace = updatedHitPointInLocalSpace - _mouseDownMapPinPlanePositionInMapLocalSpace;
                                var newDeltaInMercator = new MercatorCoordinate(newDeltaInLocalSpace.x, newDeltaInLocalSpace.z) / Math.Pow(2, mapRenderer.ZoomLevel - 1);
                                var newLocation = (_mouseDownMapPinPositionInMercatorSpace + newDeltaInMercator).ToLatLon();

                                Undo.RecordObject(target, "Changed Location");
                                mapPin.Location = newLocation;
                            }
                            Event.current.Use();
                        }
                        break;
                    case EventType.Repaint:
                        if (_isHovered || _isDragging)
                        {
                            // Change the cursor to make it obvious you can move the MapPin around.
                            EditorGUIUtility.AddCursorRect(new Rect(0, 0, 999999, 999999), MouseCursor.MoveArrow);
                        }

                        var planeY = _isDragging ? (mapRenderer.transform.localToWorldMatrix * _mouseDownMapPinPlanePositionInMapLocalSpace).y : transform.position.y;
                        var rectanglePosition = new Vector3(transform.position.x, planeY, transform.position.z);
                        Handles.DrawSolidRectangleWithOutline(
                            new Vector3[]
                            {
                                    rectanglePosition - size * mapRenderer.transform.right - size * mapRenderer.transform.forward,
                                    rectanglePosition - size * mapRenderer.transform.right + size * mapRenderer.transform.forward,
                                    rectanglePosition + size * mapRenderer.transform.right + size * mapRenderer.transform.forward,
                                    rectanglePosition + size * mapRenderer.transform.right - size * mapRenderer.transform.forward
                            },
                            new Color(0.4f, 0.4f, 0.4f, 0.4f),
                            new Color(0, 0, 0, 0));

                        if (rectanglePosition != transform.position)
                        {
                            Handles.color = rectanglePosition.y > transform.position.y ? Color.red : Color.green;
                            Handles.DrawLine(transform.position, rectanglePosition);
                        }

                        Handles.color = _isHovered ? Color.yellow : Color.green;
                        Handles.color = _isDragging ? Color.white : Handles.color;
                        Handles.RectangleHandleCap(
                            controlId,
                            rectanglePosition,
                            transform.rotation * Quaternion.LookRotation(Vector3.up),
                            size,
                            EventType.Repaint);
                        break;
                }
            }
            else
            {
                Tools.hidden = false;
            }
        }