C# RenderTexture : Click and select an object.

Hi,
I am working on a 2D project (mostly made of Canvas & UI elements) and I needed 3D dice, so I implemented them and rendered them in a RawImage using RenderTexture. The user can select which dice he wants to use so I need to be able to select them by clicking on them via the RenderTexture.
I have been looking around and have come to understand that I will need to player with raycasts, but I have no idea what to do with them.
Could someone take five minutes to explain / show me what to do (C#) ?

Here is my setup.
DiceSetup = Empty gameobject with the 3D dice prefabs & the second camera (DiceCamera).

DiceWindow = RawImage that contains the RenderTexture. It is nested in a Canvas that is used as game interface.

Dice1 = Prefab with a MeshCollider.
I am using Unity 2018.1.1f1

The idea is to click on DiceWindow at the position where Dice1 is rendered so that the prefab in DiceSetup is “selected” (ChooseDice function in my code).


EDIT TO CLARIFY :

Actual 3D dice are rolled on a plane that is hidden from the main camera and captured by a secondary camera (DiceCamera in my setup). This camera feeds a RenderTexture (a screen if you want) with the image of the dice.
My issue is that I need to click on the 3D prefab but in order to do that, I have to click on its image.
I have read about raycasts and if I understood correctly, a ray need to go from the main camera to the point I touched on the RenderTexture, which would trigger a second ray going from the second camera to the dice using the results of the first ray.
But I have absolutely no idea how to do that.


EDIT 2:

I made a light version of my project to see how the dice / rendertexture are setup.

Any help, advice is appreciated.

Thank you.

Hi I think this may work. I’m not 100% sure but it’s worth a try.

 Public Camera secondaryCam;
 
 Void Update()
   {
         RaycastHit hit;
         Ray ray = secondaryCam.ScreenPointToRay(Input.mousePosition);
         
         if (Input.GetMouseButtonDown(0))
         {
              if (Physics.Raycast(ray, out hit)) 
              {
                 Transform objectHit = hit.transform;// object hit is now accessible and you can now do what you wish, so                
                 if (objectHit.transform.gameobject.name == “Dice1”) 
                 { 
                   //do something
                 }
              }
          }
     }
 }
 //if this worked for you please mark answer as answered! Thanks!

I have been working on the problem and I have managed to have the first part work. Apparently, you can’t use a basic raycast on a Canvas. You need a GraphicRaycaster component. So I added it + a new script to the Canvas. I can get the DiceScreen and (presumably) the position data of the touch event.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class RayCast : MonoBehaviour, IPointerDownHandler 
//I have added a GraphicRaycaster component to the GameUI Canvas and added this script to it. 
//There also need to be a EventSystems in the scene to capture the Pointer data (but with UI, it is already there)
{

    public Camera diceCam;
    public GameObject selectedDice;

    GraphicRaycaster gr;
    List<RaycastResult> results;

    void Start()
    {
        gr = gameObject.GetComponent<GraphicRaycaster>(); 
        //Can't raycast on Canvas apparently
        diceCam = GameObject.Find("DiceSystem").transform.Find("DiceCam").GetComponent<Camera>();
    }

    public void OnPointerDown(PointerEventData data) 
    {
        results = new List<RaycastResult>();
        gr.Raycast(data, results); 
        //Now all the things that were touched by the graphic raycast are saved in a list.
        for (int i = 0; i < results.Count; i++)
        {
            if (results*.gameObject.name == "RawImage")* 

//this is the one we need.
{
Debug.Log(“Touched the screen!”); //yeah!!
//So here we have the fist part working. I can get the screen and I am
//guessing that somewhere in results*, the coordinates I need for the second cast*
//are waiting for me to understand what to do next…
//I need to access the coordinates of the first hit (results*) and feed*
//it to a raycast that originates from the second cam to the extrapolated point which
//would let me access the 3d prefab.

///Here is what I tried (not working).
RaycastHit hit;
Ray ray = diceCam.ViewportPointToRay(results*.screenPosition);*
if (Physics.Raycast(ray, out hit))
{
if (hit.transform.gameObject.name == “Dice1” || hit.transform.gameObject.name == “Dice2”)
{
selectedDice = hit.transform.gameObject;
}
else
{
Debug.Log("Touched object2 is " + hit.transform.gameObject.name);
}
}
///
}
}
}
}