c# – 使可放置对象捕捉到网格

我在我的游戏中有一个构建机制,我想知道我是如何做到这一点的,所以每当我放下对象时它都会对齐网格.每当我按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");
        }
    }
}

解决方法

一个更加数学的方法,你可以轻松设置网格大小(除了Lews Therin的答案)将是:

>取位置mod yourGridSize(比如,你的网格大小是64,位置是144.那么:144 mod 64 = 16)
>取mod模式并从位置减去:144 – 16 = 128
>最后,将上面的结果除以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);

令人费解?也许.有效?哎呀!

相关文章

目录简介使用JS互操作使用ClipLazor库创建项目使用方法简单测...
目录简介快速入门安装 NuGet 包实体类User数据库类DbFactory...
本文实现一个简单的配置类,原理比较简单,适用于一些小型项...
C#中Description特性主要用于枚举和属性,方法比较简单,记录...
[TOC] # 原理简介 本文参考[C#/WPF/WinForm/程序实现软件开机...
目录简介获取 HTML 文档解析 HTML 文档测试补充:使用 CSS 选...