- Home /
GraphicRaycaster not detecting UI Button only detecting UI Image
Hello
I've been working on this problem for awhile now and I just can't seem to figure it out. My GraphicRaycaster work fine but when I hover my custom cursor over a button object it will still think it's over a UI Image. This script is for my Xbox Controller because that's what my game uses. What I want is to have the GraphicRaycaster to stop getting the UI Image when my cursor is over a UI Button. My Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class CusorInput : MonoBehaviour
{
//THIS SCRIPT IS ON THE CANVAS...
public InternetCurser myIntCursor;
public GameObject CurserObject;
public Image CurserObjImage;//this will be used to get the image so that the sprite can change...
public Sprite Curser1;//normal looking curser sprite...
public Sprite Curser2;//can click on something sprite...
bool firstTargetIgnord = false;
public bool hoverdOver = false;
GraphicRaycaster myRaycaster;
PointerEventData myPointerEventData;
EventSystem myEventSystem;
GameObject myGameObject;
void Start()
{
//Fetch the raycaster from the gameobject aka the canvas...
myRaycaster = GetComponent<GraphicRaycaster>();
//fetch the eventsystem from the scene...
myEventSystem = GetComponent<EventSystem>();
}
void Update()
{
//Debug.Log("WORK!!!");
//Sets the new pointer event...
myPointerEventData = new PointerEventData(myEventSystem);
//sets the pointer event position to that of mouse position...
//Main Cursor that will be used for everything else...
myPointerEventData.position = CurserObject.transform.position;
//Create a list of raycast result...
List<RaycastResult> results = new List<RaycastResult>();
//raycast using the graphics raycaster and click position...
myRaycaster.Raycast(myPointerEventData, results);
//for every result returned, output the name of the
//gameobject on the canvas hit by the ray...
//In order for it to work it must be in update...
//once in update it will run..
if (myIntCursor.ShowCurser)
{
foreach (RaycastResult hovered in results)
{
if (hovered.gameObject.GetComponent<Button>())
{
//Debug.Log("I'm hovering over Button");
CurserObjImage.sprite = Curser2;
}
/*if (!hovered.gameObject.GetComponent<Button>())
{
Debug.Log("I'm not hovering over a button");
CurserObjImage.sprite = Curser1;
}*/
}
}
if (Input.GetButtonUp("A Button"))
{
CurserObjImage.sprite = Curser1;
foreach (RaycastResult result in results)
{
//Debug.Log("Clicked On " + name);
// Ignore the first target with raycastTarget
// as this will receive the normal click event trigger
// This prevents the first raycastTarget being invoked twice
if (!firstTargetIgnord)
{
firstTargetIgnord = true;
}
if (firstTargetIgnord)
{
if (result.gameObject.GetComponent<Button>())
{
//Debug.Log("INVOKED " + result.gameObject.name);
result.gameObject.GetComponent<Button>().onClick.Invoke();
}
/*if (result.gameObject.GetComponent<InputField>())
{
result.gameObject.GetComponent<InputField>().ActivateInputField();
myinternet.Keybourd.SetActive(true);
}*/
}
}
}
}
}
I thank anyone that comes to help. Thank You
Answer by lunarwaterstudios · Apr 22 at 07:27 PM
I have figured it out. Works really good. My Code:
public class CusorInput : MonoBehaviour
{
public InternetCurser myIntCursor;
public GameObject CursorObject;
public Image CurserObjImage;
public Sprite Curser1;
public Sprite Curser2;
public LayerMask ButtonLayerMask;
public float RaycastHitDistance;
//GraphicRaycaster
bool firstTargetIgnord = false;
GraphicRaycaster myRaycaster;
PointerEventData myPointerEventData;
EventSystem myEventSystem;
void Start()
{
myRaycaster = GetComponent<GraphicRaycaster>();
myEventSystem = GetComponent<EventSystem>();
}
void FixedUpdate()
{
RaycastHit2D Hit2D = Physics2D.Raycast(CursorObject.transform.position, -Vector2.up, RaycastHitDistance, ButtonLayerMask);
if (myIntCursor.ShowCurser)
{
myPointerEventData = new PointerEventData(myEventSystem);
myPointerEventData.position = CursorObject.transform.position;
List<RaycastResult> results = new List<RaycastResult>();
myRaycaster.Raycast(myPointerEventData, results);
if (Hit2D.collider != null)
{
CurserObjImage.sprite = Curser2;
}
if (Hit2D.collider == null)
{
CurserObjImage.sprite = Curser1;
}
if (Input.GetButtonUp("A Button"))
{
foreach (RaycastResult result in results)
{
if (!firstTargetIgnord)
{
firstTargetIgnord = true;
}
if (firstTargetIgnord)
{
if (result.gameObject.GetComponent<Button>())
{
result.gameObject.GetComponent<Button>().onClick.Invoke();
}
}
}
}
}
}
}
You have to use both Raycast2D, and GraphicRaycaster.
Answer by Pangamini · Apr 20 at 04:34 PM
It's GraphicRaycaster, it hits graphics elements of the UI. The input messages are then sent up the hierarchy from the object that's hit by the raycaster(s), and are handled by a Button. Button itself is not a raycast target, it doesn't have any shape.