Сделать привязку размещаемого объекта к сетке - PullRequest
3 голосов
/ 15 марта 2019

У меня есть механика сборки в моей игре, и мне было интересно, как я смогу сделать это так, что когда бы я ни размещал объект, он привязывался к сетке.Всякий раз, когда я нажимаю 0, он перемещает объект к моей мыши и всякий раз, когда я щелкаю по нему, помещает объект вниз.Я хочу сделать привязку к сетке при размещении, чтобы объекты не сталкивались.

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");
        }
    }
}

Ответы [ 2 ]

4 голосов
/ 15 марта 2019

Вы можете привязаться к сетке в коде, просто округлив каждую ось transform.position:

var currentPosition = transform.position;
transform.position = new Vector3(Mathf.Round(currentPosition.x),
                                 Mathf.Round(currentPosition.y),
                                 Mathf.Round(currentPosition.z));
2 голосов
/ 15 марта 2019

Более математический подход, для которого вы можете легко установить размер сетки (кроме ответа Льюса Терина), будет:

  1. Взять position mod yourGridSize (скажем, у вас размер сетки 64, а позиция 144. затем : 144 mod 64 = 16)
  2. Возьмите результат mod и вычтите из позиции: 144 - 16 = 128
  3. Наконец, разделите полученный результат на yourGridSize: 128/64 = 2

Теперь вы знаете, что ваша позиция 2 блоков в сетке. Примените эту операцию для трех осей:

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);

запутанным? Может быть. Эффективное? Черт, да!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...