Raycast textureCoord incorrect after rotating sphere

I’m attempting to use the below code to select the pixel clicked on a sphere. I was getting innacruate results from hit.textureCoord and figured out that this happens if i have sphere rotate, even if it he rotation is paused when clicking (it actually pauses while the mouse is over the sphere).

I use these coord to call a simple method that recolours the pixel red, if the sphere has rotated prior to clicking i can see a pixel turn red but it’s not where the raycast hit. If the sphere has not been rotated the pixel lines up with the ray.

I’m not sure what causes this, I assume it’s me not understanding some part of how this works. I’m hoping the solution isn’t too difficult.

 RaycastHit hit;
            if (!Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit))
            {
                return;
            }
            var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            Debug.DrawRay(ray.origin, ray.direction * 50000000, Color.red, 100f);
            Renderer renderer = hit.transform.GetComponent<Renderer>();
            MeshCollider meshCollider = hit.collider as MeshCollider;
          
            if(renderer == null || renderer.sharedMaterial == null || renderer.sharedMaterial.mainTexture == null || meshCollider == null)
            {
                return;
            }
           
            Texture2D tex = renderer.material.mainTexture as Texture2D;
            Vector2 pixelLocation = hit.textureCoord;

Can you share your code that colors the pixel? The texture coordinate you get from hit.textureCoord is in UV space, which is a local coordinate system for the mesh itself. By the way there’s an example of pretty much exactly what you’re doing in the manual here: Unity - Scripting API: RaycastHit.textureCoord Have you seen it?

If the sphere is physically rotated (by the root transform) this should work fine.

If the material is UV-offset in some way (i.e., anything other than (0,0) offset and (1,1) tiling), it won’t work and the failure mode will be exactly as you describe: the pixel comes out in the wrong place.

What kind of collider is on the sphere? If it’s a SphereCollider, then textureCoord doesn’t work (there’s absolutely nothing linking the SphereCollider to any particular part of the visible mesh, even if the mesh happens to be a sphere). It must be a MeshCollider.

1 Like

Hey, the sphere is using a meshcollider. The code to colour the pixel is simply

 Texture2D tex = (Texture2D)Sphere.materials[0].mainTexture;
            tex.SetPixel(x, y, Color.red);
            tex.Apply();

The sphere itself is rotated using the following code

 if (rotate)
        {
            transform.Rotate(Vector3.up, RotationSpeed * Time.deltaTime);
        }

The example at Unity - Scripting API: RaycastHit.textureCoord multiplies the texture coordinates by the width/height of the texture. Is your code doing that too (I don’t see it anywhere)

Hey PraetorBlue,

Yes i’m doing that, i’ve stripped out a lot of code that i posted as it’s nothing to do with this issue and i must have cut that part off by accident, I’ve seen the example you’ve given and it’s exactly what i’m doing to get the coord. Like i said, this issue is only present if i have the sphere rotating.

I’m still stuck with this, another oddity is that if i manually change the y rotation the correct pixel is still selected. Even if i allow the above script to rotate the sphere (clicking gets an offset pixel) and then manually set the rotation it will suddenly work again.

I’ve pretty much stumped with this one.