Rounding a position against the surface of an object.

Hello, I am making a block-based building system.

It is supposed to be able to place a block against any surface, aligned to a grid, regardless of the surface’s orientation. (For a space-themed ship building game)

I have already implemented the entire placement system, except that I cannot figure out how to place a block where it is supposed to be regardless of the orientation of the thing to be placed against.

My problem, specifically, is that when the surface is at a 45 degree angle, the block’s position is not rounded against the surface in one direction. (In this case, the axis around which the object was rotated.)

Here is my current code:

Vector3 RoundAgainstSurface(Vector3 v3, RaycastHit hit)
{
	Vector3 vtemp;

	// if this direction isn't directly away or towards the surface (so that it doesn't round away or towards it)
	if(Mathf.Abs(hit.normal.x) < 0.5f)
	{
		// round relative distance to the center of the object we're placing on.
		vtemp.x = hit.collider.gameObject.transform.position.x + (float) System.Math.Round(hit.point.x - hit.collider.gameObject.transform.position.x, System.MidpointRounding.AwayFromZero);
	}
	else
	{
		vtemp.x = v3.x;
	}

	if(Mathf.Abs(hit.normal.y) < 0.5f)
	{
		vtemp.y = hit.collider.gameObject.transform.position.y + (float) System.Math.Round(hit.point.y - hit.collider.gameObject.transform.position.y, System.MidpointRounding.AwayFromZero);
	}
	else
	{
		vtemp.y = v3.y;
	}

	if(Mathf.Abs(hit.normal.z) < 0.5f)
	{
		vtemp.z = hit.collider.gameObject.transform.position.z + (float) System.Math.Round(hit.point.z - hit.collider.gameObject.transform.position.z, System.MidpointRounding.AwayFromZero);
	}
	else
	{
		vtemp.z = v3.z;
	}

	//                v make it so the object's center isn't directly at the point of intersection
	return vtemp + (hit.normal/2);
}

Any help at all would be appreciated. Thanks in advance!

It seems like youre doing more work than what you need for what you want.

If you want the block to be its default rotation, you wouldnt use the surface normal to calculate any sort of rotation. If you want the block to align to the surface, thats when you want the normal information. After you do your check to see if the clicked point is a suitable spot, simply place the block at the hit.point and set its rotation to Quaternion.identity

If youre trying to snap these objects to a grid you could use

Vector3 pos= hit.point;
float gridSize = 1;
block.position = Vector3(Mathf.Round(pos.x / gridSize ) * gridSize,
                                 Mathf.Round(pos.y / gridSize ) * gridSize,
                                 Mathf.Round(pos.z / gridSize ) * gridSize);