Marker Drawer For uGUI

Back
Tags:
uGUI
Marker
Marker 2D
Example how to create your own marker drawer for uGUI.
Usage instructions:
Add this script to map GameObject, select prefab of marker, and start the scene.
2D Markers will be displayed using uGUI.
uGUIMarkerDrawer.cs
/*         INFINITY CODE         */
/*   https://infinity-code.com   */

using UnityEngine;

namespace InfinityCode.OnlineMapsExamples
{
    /// <summary>
    /// Example how to create your own marker drawer for uGUI
    /// </summary>
    [AddComponentMenu("Infinity Code/Online Maps/Examples (API Usage)/uGUIMarkerDrawer")]
    public class uGUIMarkerDrawer : MonoBehaviour
    {
        private static uGUIMarkerDrawer instance;

        /// <summary>
        /// Reference to container of the markers
        /// </summary>
        public RectTransform container;

        /// <summary>
        /// Prefab of the marker
        /// </summary>
        public GameObject prefab;

        /// <summary>
        /// Reference to the canvas
        /// </summary>
        private Canvas canvas;

        /// <summary>
        /// Gets a world camera
        /// </summary>
        private Camera worldCamera
        {
            get
            {
                if (canvas.renderMode == RenderMode.ScreenSpaceOverlay) return null;
                return canvas.worldCamera;
            }
        }

        /// <summary>
        /// This method is called each time the script is enabled
        /// </summary>
        private void OnEnable()
        {
            // Save the references to this drawer and canvas
            instance = this;
            canvas = container.GetComponentInParent<Canvas>();
        }

        /// <summary>
        /// This method is called when the script starts
        /// </summary>
        private void Start()
        {
            // Create and register a new marker drawer
            OnlineMapsControlBase.instance.markerDrawer = new Drawer(OnlineMapsControlBase.instance);
        }

        /// <summary>
        /// Drawer of the markers on canvas
        /// </summary>
        public class Drawer : OnlineMapsMarker2DDrawer
        {
            /// <summary>
            /// Reference to Control
            /// </summary>
            private OnlineMapsControlBase control;

            /// <summary>
            /// Constructor of drawer
            /// </summary>
            /// <param name="control">Reference to Control</param>
            public Drawer(OnlineMapsControlBase control)
            {
                this.control = control;
                map = control.map;

                // Subscribe to draw markers event
                map.OnMapUpdated += OnDrawMarkers;
            }

            /// <summary>
            /// Dispose the drawer
            /// </summary>
            public override void Dispose()
            {
                // Unsubscribe from draw marker event
                control.OnDrawMarkers -= OnDrawMarkers;

                // Clear the reference
                control = null;
            }

            /// <summary>
            /// This method is called when drawing markers
            /// </summary>
            private void OnDrawMarkers()
            {
                // Get corners of the map
                double tlx, tly, brx, bry;
                map.GetCorners(out tlx, out tly, out brx, out bry);

                // Draw each markers
                foreach (OnlineMapsMarker marker in OnlineMapsMarkerManager.instance.items)
                {
                    DrawMarker(marker, tlx, tly, brx, bry);
                }
            }

            /// <summary>
            /// This method is called to draw each marker
            /// </summary>
            /// <param name="marker">Marker</param>
            /// <param name="tlx">Left longitude of the map</param>
            /// <param name="tly">Top latitude of the map</param>
            /// <param name="brx">Right longitude of the map</param>
            /// <param name="bry">Bottom latitiude of the map</param>
            private void DrawMarker(OnlineMapsMarker marker, double tlx, double tly, double brx, double bry)
            {
                // Get coordinates of the marker
                double px, py;
                marker.GetPosition(out px, out py);

                // Get instance of marker from custom data
                GameObject markerInstance = marker["instance"] as GameObject;

                // If marker outside the map
                if (px < tlx || px > brx || py < bry || py > tly)
                {
                    // If there is an instance, destroy it
                    if (markerInstance != null)
                    {
                        OnlineMapsUtils.Destroy(markerInstance);
                        marker["instance"] = null;
                    }

                    return;
                }

                // If there is no instance, create it and put the reference to custom data
                if (markerInstance == null)
                {
                    marker["instance"] = markerInstance = Instantiate(instance.prefab);
                    (markerInstance.transform as RectTransform).SetParent(instance.container);
                    markerInstance.transform.localScale = Vector3.one;
                }

                // Convert geographic coordinates to screen position
                Vector2 screenPosition = control.GetScreenPosition(px, py);

                // Get rect transform of the instance
                RectTransform markerRectTransform = markerInstance.transform as RectTransform;

                // Add half height to align the marker to the bottom
                screenPosition.y += markerRectTransform.rect.height / 2;

                // Convert screen space to local space in the canvas
                Vector2 point;
                RectTransformUtility.ScreenPointToLocalPointInRectangle(markerRectTransform.parent as RectTransform, screenPosition, instance.worldCamera, out point);

                // Set position of the marker instance
                markerRectTransform.localPosition = point;
            }
        }
    }
}