Is it possible to calculate a canvas element's position so it overlaps a given gameobject?

I have a canvas and a canvas scaler on the player which is used to draw some UI elements around the player. One of these is aiming reticule. I want to make it so that when there is a valid target object, the reticule moves on top of the target object. Is there a way to convert the target object’s world position into a canvas position for the reticule? The canvas component is in world space and canvas scaler has a reference PPU of 32.

Here is some code that almost works. The only problem is that the reticule is not exactly on the target. It is moving around the object a bit depending on how close the player is to the target.

if(hasTarget)
{
	Camera mainCamera = Camera.main;
	
	if (mainCamera != null)
	{
		float distance = Vector2.Distance(parentPlayer.transform.position, targetObject.transform.position);
		float newSpacing = (distance * SpacingMultiplier) - OffsetObject.anchoredPosition.x;
		float currentSpacing = CrossHairObject.anchoredPosition.x;
		Vector2 newPos = Vector2.zero;

		newPos.x = !Approximately(currentSpacing, newSpacing) ?
			Mathf.Lerp(currentSpacing, newSpacing, SpacingSpeed * Time.deltaTime) :
			newSpacing;
		
		CrossHairObject.anchoredPosition = newPos;
		SetReticuleDots(newPos.x);
	}
}
else
{
	float currentSpacing = CrossHairObject.anchoredPosition.x;
	Vector2 newPos = Vector2.zero;
	
	newPos.x = !Approximately(currentSpacing, defaultCrossHairDistance) ?
		Mathf.Lerp(currentSpacing, defaultCrossHairDistance, SpacingSpeed * Time.deltaTime) :
		defaultCrossHairDistance;

	CrossHairObject.anchoredPosition = newPos;
	SetReticuleDots(newPos.x);
}

The Approximately() function just returns true if the difference between the floats is less than 0.05f and SetReticuleDots() calculates the spacing for the dots that are in between the player and the reticule itself. This one works fine so it’s not relevant.

Also as a side question, the reticule also seems to “sink” into the target geometry. Is it possible to make it render on top of the mesh always? The canvas is set to UI layer.

Please use the UGUI / UIToolkit / UI tags rather than the 2D-Graphics tag which relates to 2D features like 2D lighting, sprites etc. Anything “2D” relates to 2D features specifically.

I’ll change the tags for you.

Thanks.