Perso, je ferais ça en deux étapes :
On part du principe que tu instancie ton personnage devant ton personnage à une distance SPAWN_DIST.
var spawnDir:Vector3 = transform.forward * SPAWN_DIST; // direction de ton rayon
var spawnPos:Vector3; // ce sera la position où tu instancie ton monstre
OBJECTIF NUMBER ONE - TROUVER UN ENDROIT SANS MUR :
Tu lance un rayon vers spawnDir :
var hit:RaycastHit;
if(!Physics.Raycast(spawn, Vector3.down, hit, 10))
{
spawnPos = transform.position + spawnDir; // y a rien, donc pas besoin de changer
}
else
{
spawnPos = hit.point + hit.normal;
}
Là en principe, plus de soucis de mur.
OBJECTIF NUMBER TWO : INSTANCIER LE MONSTRE AU SOL :
Maintenant, on a une position de base spawnPos où on instanciera le monstre, donc on est content. Mais le faire apparaitre au sol c'est mieux.
Si tu utilise un terrain, tu peux utiliser la méthode Terrain.activeTerrain.SampleHeight() qui te donnera le point dans l'espace correspondant au sol à l'endroit que tu lui aura fourni en entrée. En gros :
spawnPos = Terrain.activeTerrain.SampleHeight(spawnPos); // tu instancie ton monstre là, au sol du terrain
Sinon si tu bosse sur des gameObejct standard, tu peux aussi faire un Raycast vers le bas (Vector3.down) et utiliser la propriété point du RaycastHit qui te donne l'endroit où ton rayon a heurté un objet (i.e le sol).
Physics.Raycast(spawnPos, Vector3.down, hit, 10);
spawnPos = hit.point; // là où tu instancie ton monstre
Naturellement dans les deux cas il faut que le pivot de ton perso soit en bas du gameObject sinon il va se retrouver au milieu du sol. 