It depends a bit on what kind of use they have. Let's assume they are static objects where each have a collider.
//I was wrong
The code is untested but should be a start for you. You could also do another raycast from above to the same object to spawn something perfectly matched its height or check the collider size.
Sorry I missed that you wanted C#, it shouldn't be to difficult to translate though as the functions are the same.
Edit:
Sorry for the confusion, I deleted the answer earlier cause I couldn't test what I wrote, and what I wrote was in a haste. So I thought I'd come back with another solution which does pretty much everything you asked, it is in UnityScript though, so you'll have to translate it to C# (I might have time later to translate it for you). This goes on the main camera as is:
/*
Instantiate an object above a collider where the user clicked (UnityScript)
*/
var obj : GameObject; //The object to spawn on click
var layerMask : LayerMask; //Mask the possible objects to hit
var layerMask2 : LayerMask; //Mask the second raycast (top down)
private var distance : float = 100; //The travel distance for the first Raycast (from the camera)
private var distance2 : float = 100; //The travel distance for the second Raycast (from above)
private var hit : RaycastHit; //The return of the hit
private var hit2 : RaycastHit; //The return of the second hit
private var ray : Ray;
private var ray2 : Ray;
private var spawnOffset : float = 0.1;
function Update () {
if (Input.GetMouseButtonDown(0)) {
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
ray.origin = transform.position;
//Debug.DrawRay (ray.origin, ray.direction * 100, Color.yellow);
if (Physics.Raycast (ray, hit, distance, layerMask)) {
//Here we shoot the raycast into the scene and instantiate the prefab
if (Physics.Raycast (hit.point+Vector3(0, distance2, 0), -Vector3.up, hit2, distance2+1, layerMask2)) {
var spawned : GameObject = Instantiate(obj, hit2.point, Quaternion.identity);
var colHeight : float = spawned.collider.bounds.extents.y;
if (spawned.rigidbody) {spwanOffset = 0.1;} else {spwanOffset = .0;}
spawned.transform.position.y += colHeight+spawnOffset;
}
}
}
// This is for you to see what actually happens in the Scene view
if (hit!=null&&hit2!=null) {
Debug.DrawLine (transform.position, hit.point, Color.red);
Debug.DrawLine (hit2.point, hit.point+Vector3(0, distance2, 0), Color.red);
}
}
So what happens is we shoot a ray from the camera's point of view where the user clicked (so if the camera is still and the user clicks in a corner of the screen space the ray will shoot on the correct position in world space). Then we shoot another ray from above down to the hit position to make sure we place the object above the point of collision (here you could use a sweeptest too if you want to make it really efficient). The object gets instantiated and we use that variable to move the object afterwards depending on its collider's height. If it has a rigidbody we also offset it to not make it jump when we place it.
The solution uses layer masks so you can pass through a roof for instance.
Edit 2:
I made a small test with how this could work, using the script above as a base: Check it out here. Use left mouse to instantiate and right mouse to rotate camera.