| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- using UnityEngine;
- using UnityEngine.UI;
- using TMPro;
- /// <summary>
- /// Handles mouse hover tooltips for event markers
- /// Shows event information when hovering over red event markers
- /// </summary>
- public class EventMarkerTooltip : MonoBehaviour
- {
- [Header("Tooltip Settings")]
- [SerializeField] private GameObject tooltipPrefab;
- [SerializeField] private Canvas tooltipCanvas;
- [SerializeField] private float showDelay = 0.5f;
- [SerializeField] private Vector2 tooltipOffset = new Vector2(10f, 10f);
- // References
- private TravelEvent associatedEvent;
- private GameObject tooltipInstance;
- private Camera mainCamera;
- private bool isHovering = false;
- private float hoverStartTime;
- // Static tooltip management (only one tooltip at a time)
- private static EventMarkerTooltip currentTooltipShowing;
- void Start()
- {
- mainCamera = Camera.main;
- if (mainCamera == null)
- mainCamera = FindFirstObjectByType<Camera>();
- // Find or create tooltip canvas
- SetupTooltipCanvas();
- }
- void Update()
- {
- // Handle mouse hover detection
- if (isHovering && tooltipInstance == null && Time.time - hoverStartTime >= showDelay)
- {
- ShowTooltip();
- }
- // Update tooltip position if showing
- if (tooltipInstance != null && isHovering)
- {
- UpdateTooltipPosition();
- }
- }
- /// <summary>
- /// Initialize this tooltip with event data
- /// </summary>
- /// <param name="travelEvent">The event this marker represents</param>
- public void Initialize(TravelEvent travelEvent)
- {
- associatedEvent = travelEvent;
- // Add collider for mouse detection if not present
- if (GetComponent<Collider>() == null)
- {
- var collider = gameObject.AddComponent<SphereCollider>();
- collider.radius = 1.5f; // Larger area for easier hovering when zoomed out
- collider.isTrigger = true;
- }
- }
- void OnMouseEnter()
- {
- if (associatedEvent == null) return;
- isHovering = true;
- hoverStartTime = Time.time;
- // Hide any other tooltips
- if (currentTooltipShowing != null && currentTooltipShowing != this)
- {
- currentTooltipShowing.HideTooltip();
- }
- }
- void OnMouseExit()
- {
- isHovering = false;
- HideTooltip();
- }
- void OnDestroy()
- {
- HideTooltip();
- }
- private void SetupTooltipCanvas()
- {
- if (tooltipCanvas == null)
- {
- // Find existing UI canvas or create one
- tooltipCanvas = FindFirstObjectByType<Canvas>();
- if (tooltipCanvas == null)
- {
- // Create a new canvas for tooltips
- GameObject canvasObject = new GameObject("EventTooltipCanvas");
- tooltipCanvas = canvasObject.AddComponent<Canvas>();
- tooltipCanvas.renderMode = RenderMode.ScreenSpaceOverlay;
- tooltipCanvas.sortingOrder = 1000; // High sorting order to appear on top
- // Add Canvas Scaler for responsive UI
- var scaler = canvasObject.AddComponent<CanvasScaler>();
- scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
- scaler.referenceResolution = new Vector2(1920, 1080);
- // Add GraphicRaycaster for UI interaction
- canvasObject.AddComponent<GraphicRaycaster>();
- }
- }
- }
- private void ShowTooltip()
- {
- if (tooltipInstance != null || associatedEvent == null) return;
- // Create tooltip from prefab or default
- if (tooltipPrefab != null)
- {
- tooltipInstance = Instantiate(tooltipPrefab, tooltipCanvas.transform);
- }
- else
- {
- tooltipInstance = CreateDefaultTooltip();
- }
- // Set tooltip content
- SetTooltipContent();
- // Position tooltip
- UpdateTooltipPosition();
- currentTooltipShowing = this;
- }
- private GameObject CreateDefaultTooltip()
- {
- // Create default tooltip UI
- GameObject tooltip = new GameObject("EventTooltip");
- tooltip.transform.SetParent(tooltipCanvas.transform, false);
- // Add background image
- var bgImage = tooltip.AddComponent<Image>();
- bgImage.color = new Color(0.05f, 0.05f, 0.05f, 0.95f); // Darker, more opaque background for better readability
- // Add subtle border/outline effect
- var outline = tooltip.AddComponent<Outline>();
- outline.effectColor = new Color(0.3f, 0.3f, 0.3f, 1f);
- outline.effectDistance = new Vector2(1f, 1f);
- // Add content layout
- var layoutGroup = tooltip.AddComponent<VerticalLayoutGroup>();
- layoutGroup.padding = new RectOffset(15, 15, 12, 12); // More padding for better spacing
- layoutGroup.spacing = 8f; // More spacing between elements
- layoutGroup.childAlignment = TextAnchor.MiddleLeft;
- layoutGroup.childControlWidth = true;
- layoutGroup.childControlHeight = true;
- layoutGroup.childForceExpandWidth = false;
- layoutGroup.childForceExpandHeight = false;
- // Add content size fitter
- var sizeFitter = tooltip.AddComponent<ContentSizeFitter>();
- sizeFitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
- sizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
- // Create title text
- GameObject titleObject = new GameObject("Title");
- titleObject.transform.SetParent(tooltip.transform, false);
- var titleText = titleObject.AddComponent<TextMeshProUGUI>();
- titleText.text = "Event Title";
- titleText.fontSize = 18f; // Larger font for better readability
- titleText.fontWeight = FontWeight.Bold;
- titleText.color = Color.white;
- // Create description text
- GameObject descObject = new GameObject("Description");
- descObject.transform.SetParent(tooltip.transform, false);
- var descText = descObject.AddComponent<TextMeshProUGUI>();
- descText.text = "Event description...";
- descText.fontSize = 14f; // Larger font for better readability
- descText.color = new Color(0.9f, 0.9f, 0.9f, 1f); // Lighter gray for better contrast
- descText.textWrappingMode = TMPro.TextWrappingModes.Normal; // Updated property name
- // Set max width for text wrapping
- var titleRect = titleText.GetComponent<RectTransform>();
- titleRect.sizeDelta = new Vector2(350f, 0f); // Wider tooltip for better text layout
- var descRect = descText.GetComponent<RectTransform>();
- descRect.sizeDelta = new Vector2(350f, 0f);
- return tooltip;
- }
- private void SetTooltipContent()
- {
- if (tooltipInstance == null || associatedEvent == null) return;
- // Find text components
- var textComponents = tooltipInstance.GetComponentsInChildren<TextMeshProUGUI>();
- if (textComponents.Length >= 2)
- {
- // Set title
- textComponents[0].text = GetEventTitle();
- // Set description
- textComponents[1].text = GetEventDescription();
- }
- else
- {
- // Fallback for different tooltip structures
- var singleText = tooltipInstance.GetComponentInChildren<TextMeshProUGUI>();
- if (singleText != null)
- {
- singleText.text = $"{GetEventTitle()}\n{GetEventDescription()}";
- }
- }
- }
- private string GetEventTitle()
- {
- if (associatedEvent == null) return "Unknown Event";
- // Get event type icon
- string icon = associatedEvent.eventType switch
- {
- EventType.Combat => "⚔️",
- EventType.Trading => "💰",
- EventType.Discovery => "🔍",
- EventType.Social => "💬",
- EventType.Hazard => "⚠️",
- EventType.Rest => "🏕️",
- EventType.Mystery => "❓",
- _ => "📍"
- };
- return $"{icon} {associatedEvent.eventName}";
- }
- private string GetEventDescription()
- {
- if (associatedEvent == null) return "No information available.";
- string description = associatedEvent.eventDescription;
- // Add event type information
- string typeInfo = associatedEvent.eventType switch
- {
- EventType.Combat => "Combat encounter - approach to engage",
- EventType.Trading => "Trading opportunity - approach to trade",
- EventType.Discovery => "Something to discover - approach to investigate",
- EventType.Social => "Social encounter - approach to interact",
- EventType.Hazard => "Environmental hazard - approach with caution",
- EventType.Rest => "Rest opportunity - approach to recover",
- EventType.Mystery => "Mysterious event - approach to uncover",
- _ => "Unknown event type"
- };
- // Add rarity information
- string rarityInfo = associatedEvent.rarity switch
- {
- EventRarity.VeryCommon => "Very Common",
- EventRarity.Common => "Common",
- EventRarity.Uncommon => "Uncommon",
- EventRarity.Rare => "Rare",
- EventRarity.VeryRare => "Very Rare",
- EventRarity.Legendary => "Legendary",
- _ => "Unknown"
- };
- return $"{description}\n\nType: {typeInfo}\nRarity: {rarityInfo}\n\n<i>Move close to trigger this event</i>";
- }
- private void UpdateTooltipPosition()
- {
- if (tooltipInstance == null || mainCamera == null) return;
- // Get mouse position
- Vector3 mousePos = Input.mousePosition;
- // Add offset
- mousePos.x += tooltipOffset.x;
- mousePos.y += tooltipOffset.y;
- // Ensure tooltip stays on screen
- RectTransform tooltipRect = tooltipInstance.GetComponent<RectTransform>();
- if (tooltipRect != null)
- {
- // Get screen bounds
- float screenWidth = Screen.width;
- float screenHeight = Screen.height;
- // Get tooltip size
- Vector2 tooltipSize = tooltipRect.sizeDelta;
- // Adjust position to keep tooltip on screen
- if (mousePos.x + tooltipSize.x > screenWidth)
- {
- mousePos.x = screenWidth - tooltipSize.x - 10f;
- }
- if (mousePos.y + tooltipSize.y > screenHeight)
- {
- mousePos.y = mousePos.y - tooltipSize.y - tooltipOffset.y * 2;
- }
- // Set position
- tooltipRect.position = mousePos;
- }
- }
- private void HideTooltip()
- {
- if (tooltipInstance != null)
- {
- Destroy(tooltipInstance);
- tooltipInstance = null;
- }
- if (currentTooltipShowing == this)
- {
- currentTooltipShowing = null;
- }
- }
- }
|