I have a script, it is used to detect if a province is being hovered over or clicked, and if it is clicked, it is selected, with the UI appearing over the screen. However, when I select a province and then try to click the build button in my UI, the ray goes through the button and deselects the province without clicking the button. (HALF FIXED SEE EDIT BELOW)
using UnityEngine;using UnityEngine.UI;using UnityEngine.EventSystems;using System.Collections.Generic;public class ProvinceSelection : MonoBehaviour{ public GameObject actionPanel; public BuildStructure provinceBuilder; public float hoverBrightness = 1.5f; public float originalBrightness = 1.0f; private Material provinceMaterial; private bool isSelected = false; private static GameObject selectedProvince; private Camera mainCamera; private int provinceLayerMask; void Start() { actionPanel.SetActive(false); mainCamera = GameObject.FindGameObjectWithTag("Player").GetComponent<Camera>(); provinceMaterial = GetComponent<Renderer>().material; // Set the province layer mask to ignore raycasts provinceLayerMask = 1 << LayerMask.NameToLayer("Provinces"); } void Update() { if (isSelected || IsHovering()) { provinceMaterial.SetFloat("_Brightness", hoverBrightness); } else { provinceMaterial.SetFloat("_Brightness", originalBrightness); } if (isSelected && Input.GetMouseButtonDown(0)) { // Check if the mouse is over UI if (!IsPointerOverButton()) { RaycastHit hit; Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition); // Perform a raycast only against the provinces layer mask if (!Physics.Raycast(ray, out hit, Mathf.Infinity, provinceLayerMask)) { DeselectProvince(); } } } } void OnMouseDown() { if (selectedProvince != null && selectedProvince != gameObject) { selectedProvince.GetComponent<ProvinceSelection>().DeselectProvince(); } // Perform a raycast to check for UI elements between the camera and the clicked point Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition); RaycastHit hitInfo; bool hitUI = Physics.Raycast(ray, out hitInfo, Mathf.Infinity, LayerMask.GetMask("UI")); // If a UI element is hit, return without selecting the province if (hitUI) { return; } // Proceed with province selection isSelected = true; selectedProvince = gameObject; Debug.Log("Clicked on province: " + gameObject.name); actionPanel.SetActive(true); Text provinceNameText = actionPanel.GetComponentInChildren<Text>(); if (provinceNameText != null) { provinceNameText.text = gameObject.name; } else { Debug.LogWarning("No Text component found in the action panel."); } provinceBuilder.SetSelectedProvince(gameObject); } public void DeselectProvince() { isSelected = false; selectedProvince = null; actionPanel.SetActive(false); } bool IsHovering() { if (mainCamera != null) { Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit)) { return hit.collider.gameObject == gameObject; } } return false; } bool IsPointerOverButton() { PointerEventData eventData = new PointerEventData(EventSystem.current); eventData.position = Input.mousePosition; // Create a list of raycast results List<RaycastResult> results = new List<RaycastResult>(); EventSystem.current.RaycastAll(eventData, results); // Check if any of the raycast results are UI buttons foreach (RaycastResult result in results) { if (result.gameObject.GetComponent<Button>() != null) { return true; } } return false; }}
EDIT: I now have figured out how to stop the raycast from deselecting the provinces, but there is still another issue: When the camera is moved to see the map from a different angle, the buttons are moved so that provinces are underneath them, and when the button is pressed, the raycast goes through the button and selects the province underneath.