Ok so I have this script and have a snapping issue that makes no sense. I create a chunk with a for statement and then I create a few structures with for statements also. When I place a block it usually work but sometimes it decides to place the block inside another(same location). How can I eliminate this issue? I think its a rounding issue! Also while I have attention is there a way to not have the mouse and center this action where you create the gui crosshair? How can I make the gui crosshair? Just use the games gui function?
void Update()
{
Ray ray = camera.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0));
Vector3 G = new Vector3(Mathf.Round(hit.point.x), Mathf.Ceil(hit.point.y), Mathf.Round(hit.point.z));
if(Physics.Raycast(ray, out hit))
{
if(Input.GetMouseButtonDown(0))
{
Destroy(hit.collider.gameObject);
}
if(Input.GetMouseButtonDown(1))
{
Instantiate(prefab, G, Quaternion.identity);
}
}
}
The best I understand is that you have a voxel-based world type game. You pick a position a short bit in front of the camera (round it off) and place a block there. But you aren’t doing anything in the code above to check if there is already a block there. So nothing is stopping the game from creating the block at the same place as other blocks.
The fix is “simple” – you don’t create a block if there is one already there. (Usually, voxel-based games place blocks next to the face of the block you are looking at, but it seems you simply place it in front of the camera.) So, in your case, you probably want Physics.OverlapSphere()
or similar to detect if there is something already there at G
. In the simplest case:
if (Physics.OverlapSphere(G, 0.1f).Length == 0) // 0 colliders are within 0.1f around location G
// Your block placing code
Well I finally figured it out after taking a break from the project… I was so close with original code. This is what worked out for me…
void Update()
{
Ray ray = camera.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0));
if(Physics.Raycast(ray, out hit))
{
if(Input.GetMouseButtonDown(0))
{
Destroy(hit.collider.gameObject);
}
if(Input.GetMouseButtonDown(1))
{
if(prefab != null)
Instantiate(prefab, hit.transform.position + hit.normal, Quaternion.identity);
else
return;
}
}