Unity Cone Hit Test Spotlight Lits Light Object On Object Test

public static class SpotLightCastExtension
{
	public static bool InLineOfSight(this UnityEngine.Light light, Vector3 targetWorldPosition, System.Predicate<RaycastHit> collisionTest = null)
	{
		Transform lightTransform = light.transform;
		return ConeCastTest(lightTransform.position, lightTransform.forward, light.spotAngle, light.range, targetWorldPosition, collisionTest);
	}

	public static bool ConeCastTest(Vector3 sourcePosition, Vector3 forward, float openingAngle, float range, Vector3 testPosition, System.Predicate<RaycastHit> validHit = null)
	{
		Vector3 dirDetector = (testPosition - sourcePosition).normalized;
		bool visible = Vector3.Distance(testPosition, sourcePosition) <= range;

		Vector3 start = sourcePosition + forward * range;
		Vector3 projectedDetectedPositionEnd = sourcePosition + dirDetector * range;
		float detectorConeDistance = Vector3.Distance(start, projectedDetectedPositionEnd);
		// if projected object position towards center of light both at end
		// is further distanced than the openAngle max distance
		if (detectorConeDistance > 4 * openingAngle * Mathf.Deg2Rad)
		{
			visible = false;
		}
		// Cast light towards detector, is it blocked by a collider?
		else if (visible 
		    	&& Physics.Linecast(sourcePosition, projectedDetectedPositionEnd, out RaycastHit hit) 
			    && validHit is not null 
			    && !validHit.Invoke(hit))
		{
			visible = false;
		}
		
		return visible;
	}
}
Clever Cow