Find which part of an image was clicked

I have an image, and I need to getpixel at the click location. For this to work I need to know the part of the image I clicked. I can’t do this using Input.GetMousePosition, as my image may not be the same size as the screen.

//Get the object using raycast.
//Save the mouse position when you clicked.
//Get the texture from the object.
//This will yield 3 variables:
GameObject screenObject;
Texture2D texture;
Vector2 mouseClickPosition;

//To get the pixel clicked on the texture we need the mouse position relative to the texture.

//Get the screen size
Vector2 screenSize = new Vector2(Screen.width, Screen.height);
//Get the texture size
Vector2 textureSize = new Vector2(texture.width, texture.height);
//Get the screen position of the texture (This will be the center of the image)
Vector2 textureScreenPosition = Camera.main.WorldToScreenPoint(screenObject.transform.position);
//Get the 0,0 position of the texture:
Vector2 textureStartPosition = textureScreenPosition - textureSize / 2;
//Subtract the 0,0 position of the texture from the mouse click position.
Vector2 relativeClickPosition = mouseClickPosition - textureStartPosition;


/*Simple test example*/
//Clicked at 500,500

//Example screensize of 1000,1000
//Example textureSize of 300,300
//Example texture position of 400,400
//Texture Start Position will be {400,400} - {150, 150} = {250,250}
//The relative click position = {500, 500} - {250, 250} = {250, 250}
//The texture of size 300x300 got clicked on pixel {250,250}

hmmm. if you want to paint a gameobect in your scene it might be eaiser to do a raycast with the mouse.

if you get your hit point relative to the object’s position then you can calculate from there.

using UnityEngine;
using System.Collections;

public class painer : MonoBehaviour {
	public GameObject g;
	public Texture2D t; 

	public float x,y;
	void Start () {

		t = new Texture2D (25, 25);
		g = GameObject.CreatePrimitive (PrimitiveType.Cube);
		g.transform.localScale = new Vector3 (3, 3, 3);
		g.transform.renderer.material.mainTexture = t;
		g.transform.position = Camera.main.transform.position + (Camera.main.transform.forward * 10);
        }
	
	// Update is called once per frame
	void Update () {
		if (Input.GetMouseButton (0)) {
			RaycastHit hit;
			if(g.collider.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition),out hit,1000))
			   {
				x = g.transform.position.x-hit.point.x;
				x = x/g.transform.localScale.x;
				x+=.5f;
				y = g.transform.position.y-hit.point.y;
				y = y/g.transform.localScale.y;
				y+=.5f;
                t.SetPixel(Mathf.RoundToInt(x*t.width),Mathf.RoundToInt(y*t.height),Color.green);
				t.Apply();


			}}}
	
	}

This seems to work well enough for me with a plane and a camera in the variables:

        Vector3 mousePosition = Input.mousePosition;
        Ray screenPosition = _cam.ScreenPointToRay (mousePosition);
        if (!_plane.GetComponent<Collider> ().Raycast (screenPosition, out RaycastHit hit, 1000))
        {
            return;
        }

        Vector3 hitPoint = _cam.WorldToScreenPoint (hit.point);
        Vector3 planeMin = _cam.WorldToScreenPoint (_plane.GetComponent<MeshRenderer> ().bounds.min);
        Vector3 planeMax = _cam.WorldToScreenPoint (_plane.GetComponent<MeshRenderer> ().bounds.max);
        float xProportion = Mathf.InverseLerp (planeMin.x, planeMax.x, hitPoint.x);
        float yProportion = Mathf.InverseLerp (planeMin.y, planeMax.y, hitPoint.y);
        float xPoint = xProportion * sourceImage.width;
        float yPoint = yProportion * sourceImage.height;
        Vector2 startPosition = new Vector2 (xPoint, yPoint);