How to push a kinematic object so it does not go through a wall?

Hi, I’m working on spawning game objects and placing them in the world by using raycasing. I essentially get an object from a list in the GUI, this object spawns attached to the mouse pointer, when I click I can place the object and the set it’s rotation with another click.

The problem is the object has a radius, and when raycasting the user is able to place objects ‘on’ walls, because I’m setting the kinematic object’s transform.position.

Is there any way to push off from walls so the object doesn’t go through them and can’t be glued on to walls only flat (floor-like) surfaces? Ideally by the radius of the object.

I’m using kinematic objects because the game I’m making uses a really simple system to move around based on mouse-click (raycast) locations. But I can’t have my guys sticking half way through a wall.
The object has a kinematic rigidbody and a convex trigger mesh collider in the shape of a cylinder.

Here’s what my raycaster code looks like so far:

//This is the object to be spawned
	public GameObject objectToSpawn;
	public GameObject facingProjector;

	public float rotationSpeed = 10.0f;

	public bool debug = false;

	//This is the actual camera we reference in the update loop, set in Start()
	private Camera _camera;
	//to check if the object is set, otherwise will not activate
	private bool objectSelected = false;
	private bool locationSet = false;
	private bool rotationSet = false;
	private bool projectorActive = false;

	private Quaternion projectorDefaultFacing;

	private int unitLayer;

	private float clearanceRadius = 0.0f;
	
	void Start()
	{
		_camera = Camera.main;
		projectorDefaultFacing = Quaternion.identity;
		//GameObject instance = Instantiate (facingProjector, Vector3.zero, projectorDefaultFacing) as GameObject;
		//facingProjector = instance;
		facingProjector.SetActive (false);
		unitLayer = LayerMask.NameToLayer("Unit");
	}
	
	// Update is called once per frame
	void Update () {
		Ray ray;
		RaycastHit hit;

		//If there's no object selected any click will attach the object to the mouse pointer to edit it's location and rotation
		//If the object is a trooper, or Unit, we have to watch for clearance radius so we can't spawn the object in walls
		if (!objectSelected) {
			ray = _camera.ScreenPointToRay(Input.mousePosition); 
			
			//If we hit...
			if(Physics.Raycast (ray, out hit, 100) && !UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject())
			{
				if(hit.transform.gameObject.tag != "Terrain"){
					if(debug)Debug.DrawRay(ray.origin, ray.direction * hit.distance, Color.cyan);
					if(Input.GetMouseButton(0)){
						if(debug)Debug.DrawRay(ray.origin, ray.direction * hit.distance, Color.green);
						objectToSpawn = hit.transform.parent.transform.gameObject;
						objectSelected = true;
						if(objectToSpawn.tag == "Unit"){
							clearanceRadius = objectToSpawn.GetComponent<UnitInfo>().clearanceRadius;
						}
					}	
				}else{
					if(debug)Debug.DrawRay(ray.origin, ray.direction * hit.distance, Color.magenta);
				}
			}
		}

		//Here object is selected, and is attached to the mouse until the button is released or a click happens if it's a new object
		//When the mouseUp event happens the object's location is set
		if (objectSelected && !locationSet && !rotationSet) {

			//Set up our ray from screen to scene
			ray = _camera.ScreenPointToRay(Input.mousePosition); 

			//If we hit...
			if(Physics.Raycast (ray, out hit, 100, unitLayer) && !UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject())
			{
				if(debug)Debug.DrawRay(ray.origin, ray.direction * hit.distance, Color.yellow);
				//if the hit was registered on terrain, we can't place things on top of non-terrain
				if(hit.transform.gameObject.tag == "Terrain"){
					objectToSpawn.transform.position = hit.point;
					if(Input.GetMouseButtonUp(0)){
						SetLocation();
					}
				}
			}
		}
		//Object has a desired location, now rotation is set to follow the mouse on X/Z plane
		//When a click happens it will set the rotation and un-set the object
		if (objectSelected && locationSet && !rotationSet) {
			if(projectorActive == false){
				if(debug)Debug.Log("Activating Projector!");
				facingProjector.SetActive(true);
				projectorActive = true;
				facingProjector.transform.position = objectToSpawn.transform.position;
				facingProjector.transform.rotation = objectToSpawn.transform.rotation;
			}
			//active rotation setting loop
			SetRotation();
		}
		//Once location and rotation are set, the system resets, because there's no object
		if (locationSet && rotationSet) {
			objectSelected = false;
			locationSet = false;
			rotationSet = false;
		}
	}

	public void SpawnThisObject(GameObject spawnableObject){
		objectToSpawn = Instantiate(spawnableObject, Vector3.zero, Quaternion.identity) as GameObject;
		objectSelected = true;
		if(debug)Debug.Log ("Object Set!");
	}

	public void SetLocation(){
		Ray ray;
		RaycastHit hit;
		//Set up our ray from screen to scene
		ray = _camera.ScreenPointToRay(Input.mousePosition); 
		
		int unitLayer = LayerMask.NameToLayer("Unit");
		if (Physics.Raycast (ray, out hit, 100, unitLayer) && !UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject ()) {

			//if the hit was registered on terrain, we can't place things on top of non-terrain
			if(hit.transform.gameObject.tag == "Terrain"){
				if(debug)Debug.DrawRay(ray.origin, ray.direction * hit.distance, Color.green);
				//check surrounding area around object to make sure it fits?
				objectToSpawn.transform.position = hit.point;
				locationSet = true;
				if(debug)Debug.Log ("Location Set!");
			}
		}
	}

	public void SetRotation(){

		Ray ray;
		RaycastHit hit;
		//Set up our ray from screen to scene
		ray = _camera.ScreenPointToRay(Input.mousePosition); 

		if (Physics.Raycast (ray, out hit, 100, unitLayer) && !UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject ()) {
			if((hit.point - objectToSpawn.transform.position) != Vector3.zero){
				//rotation leveling, so object spawned doesn't look 'up' or 'down' only side to side
				Vector3 hitPos = new Vector3(hit.point.x, 0, hit.point.z);
				Vector3 objectPos = new Vector3(objectToSpawn.transform.position.x, 0, objectToSpawn.transform.position.z);
				Quaternion targetRotation = Quaternion.LookRotation(hitPos - objectPos);
				objectToSpawn.transform.rotation = Quaternion.Slerp(objectToSpawn.transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
				facingProjector.transform.rotation = Quaternion.Slerp(facingProjector.transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
			}
		}
		if (Input.GetKeyDown(KeyCode.Return) || Input.GetMouseButtonDown(0)){
			if(debug)Debug.Log("Rotation Set!");
			rotationSet = true;
			facingProjector.transform.rotation = projectorDefaultFacing;
			facingProjector.SetActive(false);
			projectorActive = false;
		}
	}

the hit point holds info about the surface normal. add the normal times radius to the hit point. then, raycast again,down. that’s your spawn point. gets tricky in corners though. depending on existing corner angles you could check all directions, or against each hit point… depends on complexity.