Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make a placeable object snap to grid

I have a build mechanic in my game and I was wondering how I could make it so whenever I was placing the object down it would snap to a grid. Whenever I press 0 it moves the object to my mouse and whenever I click it places the object down. I want to make it snap to a grid when placing so objects dont collide.

using UnityEngine;
using UnityEngine.AI;

public class GroundPlacementController : MonoBehaviour
{
    [SerializeField]
    private GameObject placeableObjectPrefab;
    public NavMeshObstacle nav;


    [SerializeField]
    private KeyCode newObjectHotkey = KeyCode.A;
    
    private GameObject currentPlaceableObject;


    private float mouseWheelRotation;

    



    private void Update()
    {
        HandleNewObjectHotkey();
        nav = GetComponent<NavMeshObstacle>();
        if (currentPlaceableObject != null)
        {
            MoveCurrentObjectToMouse();
            RotateFromMouseWheel();
            ReleaseIfClicked();



        }
    }

    private void HandleNewObjectHotkey()
    {
        if (Input.GetKeyDown(newObjectHotkey))
        {
            if (currentPlaceableObject != null)
            {
                Destroy(currentPlaceableObject);
               
            }
            else
            {
                currentPlaceableObject = Instantiate(placeableObjectPrefab);


            }
        }

    }
    

    private void MoveCurrentObjectToMouse()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

        RaycastHit hitInfo;
        if (Physics.Raycast(ray, out hitInfo))
        {
            currentPlaceableObject.transform.position = hitInfo.point;
            currentPlaceableObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, hitInfo.normal);
            currentPlaceableObject.GetComponent<NavMeshObstacle>().enabled = false;


        }
    }

    private void RotateFromMouseWheel()
    {
        Debug.Log(Input.mouseScrollDelta);
        mouseWheelRotation += Input.mouseScrollDelta.y;
        currentPlaceableObject.transform.Rotate(Vector3.up, mouseWheelRotation * 90f);
    }

    private void ReleaseIfClicked()
    {
        if (Input.GetMouseButtonDown(0))
        {
            
            currentPlaceableObject.GetComponent<NavMeshObstacle>().enabled = true;
            print("disabled");
            currentPlaceableObject = null;
            print("removed prefab");
        }
    }
}
like image 648
Cri Avatar asked Nov 26 '25 02:11

Cri


2 Answers

You can snap to grid in code by simply rounding each axis of the transform.position:

var currentPosition = transform.position;
transform.position = new Vector3(Mathf.Round(currentPosition.x),
                                 Mathf.Round(currentPosition.y),
                                 Mathf.Round(currentPosition.z));
like image 124
Lews Therin Avatar answered Nov 27 '25 16:11

Lews Therin


A more mathematical approach, and one that you can easily set the grid size for (other than Lews Therin's answer) would be to:

  1. Take position mod yourGridSize (say, your grid size is 64 and the position is 144. then: 144 mod 64 = 16)
  2. Take the mod result and subtract from position: 144 - 16 = 128
  3. Finally, divide the above result by yourGridSize: 128 / 64 = 2

Now you know your position is 2 blocks into the grid. Apply this operation for the three axis:

var yourGridSize = 64;

var currentPosition = currentPlaceableObject.transform.position;
currentPlaceableObject.transform.position = new Vector3(((currentPosition.x - (currentPosition.x % yourGridSize)) / yourGridSize) * yourGridSize,
                                                        ((currentPosition.y - (currentPosition.y % yourGridSize)) / yourGridSize) * yourGridSize,
                                                        ((currentPosition.z - (currentPosition.z % yourGridSize)) / yourGridSize) * yourGridSize);

Convoluted? Maybe. Effective? Heck yes!

like image 33
fhcimolin Avatar answered Nov 27 '25 14:11

fhcimolin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!