Question regarding sending clicks to another UI canvas.
This is a weird problem and it's due to how I started this project (but just going back to start and redoing it better is not really viable right now).
On this project I have an image (displaying a render texture captured from a camera) on the canvas that detects a click and then translates that to space relative to a camera to cast a ray to interact with an object in 3D space. Now we want to switch to having those object be UI objects. However the problem is we have this one render texture being projected onto two different displays of sorts. One display gets extra information overlaid onto it and that's the one that can actually interact with it by clicking on it (the control display basically while other is just a "display" display).
So the question is, is there a good way to do the same as I did, that is detecting clicks on a render texture sort of thing and sending them to another space (in this case a UI button rather than a collider's "OnClick" thing)? Is that even the right way of thinking about that?
Answer by cPetro · Mar 26, 2020 at 05:16 AM
I finally got it.
Used GraphicRayster to do it. Used some math to get relative position target canvas compared to size of image, created eventdata using that position, did the raycast, and it works.
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections.Generic;
public class UIRaycast : MonoBehaviour, IPointerClickHandler
{
public GraphicRaycaster targetCanvas;
private RectTransform thisRect;
void Start()
{
thisRect = GetComponent<RectTransform>();//store this object's RectTransform for later
}
public void OnPointerClick(PointerEventData eventData)
{
Vector2 localCursor;
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(thisRect, eventData.position, eventData.pressEventCamera, out localCursor)) //just in case this gets triggered somehow without actually clicking on image
Debug.Log("Did not click inside the Image");
else
{
localCursor += new Vector2(thisRect.rect.width * thisRect.pivot.x, thisRect.rect.height * thisRect.pivot.y);//current image is centered, this offsets it by the midpoint so that the localCursor value is 0,0 at bottom left and image's width/height at top right
RectTransform targetCanvasRect = targetCanvas.GetComponent<RectTransform>();//get the transform of target canvas for next step
localCursor = localCursor * (targetCanvasRect.sizeDelta / thisRect.sizeDelta);//translate cursor position into position relative to canvas, so 0,0 is still bottom left but top right is now canvas width/height
List<RaycastResult> results = new List<RaycastResult>(); //create list to hold raycast hits
eventData.position = localCursor;//replace eventdata's position with our new updated position
targetCanvas.Raycast(eventData, results);//do raycast to target canvas
foreach (RaycastResult result in results)
{
Debug.Log("Hit " + result.gameObject.name);
Button targetButton = result.gameObject.GetComponent<Button>(); //get button component of hit object
if (targetButton != null)//make sure it hit a button
targetButton.onClick.Invoke();//click button
}
}
}
}
This is awesome, but for my weird problem, I don't have a canvas on the other side. I have different 3d object which I'm rendering to a render texture to show in canvas. Now I want to detect clicks on 3d object via canvas
Your answer
Follow this Question
Related Questions
Button prefab is causing wrong prefab to trigger 2 Answers
UI canvas changing size when game plays? 0 Answers
How to click button multiple times 0 Answers
button pressing the button next to it?! 2 Answers
Android UI push Multiple buttons Help 0 Answers