Get transparency of one pixel

Hi. I have C# function like this:

void Update () {
	
	if (!Input.GetMouseButtonDown(0))
	{
		return;
	}
	
	var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
	
 	RaycastHit[] hits;
	        hits = Physics.RaycastAll(ray);

		for (int i=0; i < hits.Length; i++)
		{
			Debug.Log(hits*.transform);*
  •   	}*
    
  • }*
    The function catchs mouse click position and lists which of object have we clicked. It’s works fine, but now I want to add checking, whether the texture PNG is transparency in clicked point. Simply - when we click in invisible part of picture, function avoids this object and notices just another objects which was clicked.
    I have no idea how to check one exact point properties (whats more - from raycast coordinates) and how to find the alpha channel. Could somebody prompt me something?
    Thanx!

What you are asking for is not not normal in a 3D environment, and difficult to do. Shaders often use multiple textures. Sometimes transparency is in the texture, sometimes it is done with a mask, sometimes it is determined by the blending of multiple textures. Sometimes a texture is really an atlas of textures. In addition, an object may have a transparent area that the ray first hits, but would hit a non-transparent area as it pass through the back of the mesh. And in the end, the collider that is reporting through your Raycast and the mesh/texture are different components.

If your object/mesh is a plane, and if you are using a simple shader, and if your material offsets are set to their defaults, you might be able to do it by:

  • Translate the RaycastHit.point to local coordinates of the object
  • Translate the coordinates to a UV system (0 to 1) based on the object size.
  • Use Texture2D.GetPixel() or Texture2D.GetPixelBilinear()
  • Examine the alpha value of the color returned

As a limited alternative, note that you can make changes to the collider. You can change the sizes. You can add multiple colliders of different types to a game object. You can put colliders on empty child objects. I don’t know your application, but you can create a tighter bounding for your image by manipulating the collider.

I’m sorry, that so late, but I eventually resolve the problem. You’ve right, robertbu, it was possible for so easy situation as mine - my game is quite simply, I use one texture (set in MeshRender), the transparency is wrote in picture and in Shader (Transparent/Diffuse) and every object is a plane (cause actually it is 2D game :stuck_out_tongue: ).

using UnityEngine;
using System.Collections;

public class RayCasting : MonoBehaviour {
		
	void Update () {
		
		if (!Input.GetMouseButtonDown(0))
		{
			return;
		}
		
		var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
		RaycastHit[] hits = Physics.RaycastAll(ray);
		
		Vector3 v;
		bool[] transparent = new bool[hits.Length];
		
		for (int i=0; i < hits.Length; i++)
		{
			Texture2D pic = hits*.transform.gameObject.renderer.material.mainTexture as Texture2D;*
  •  	// - Translate the RaycastHit.point to local coordinates of the object*
    

v = hits_.transform.worldToLocalMatrix.MultiplyPoint(hits*.point);*_

* // - Translate the coordinates to a UV system (0 to 1) based on the object size.*
* float xPic = 10 - (v.x + 5);*
* float yPic = v.y + 5;*

* // - Use Texture2D.GetPixel() or Texture2D.GetPixelBilinear()*
* // - Examine the alpha value of the color returned*
_ if(pic.GetPixel((int)((xPic/10)pic.width),(int)((yPic/10)pic.height)).a).a < 0.5)
transparent = true; //pixel is transparent
Debug.Log(hits.transform);

* }*_

* int res = 0;*
* if(hits.Length != 0)*
* res = exam(hits, transparent);*
* //if front checking function found something*
* //we remove it*
* if(res != hits.Length)*
* Destroy(hits[res].transform.gameObject);*
* }*
* // function which check, what is on front*
* int exam(RaycastHit[] hits, bool[] t)*
* {*
* float tmp = 100;*
* int resRay = hits.Length;*

* for(int i = 0; i < hits.Length; i++)*
* {*
if((hits_.transform.position.z < tmp) && !t*)
{
tmp = hits.transform.position.z;
resRay = i;
}
}
return resRay;
}
}*

Funny, but the hardest was computing the coordinates from “LocalMatrix” to pixels of texture - they was set in completely different way. Maybe wiser would be to think about this UV system, but eventually it work :slight_smile:
So thanks, robertbu, you told me it’s possible, so I give you plus._