You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中如何让待放置GameObject与已放置对象产生碰撞?

解决方案

1. 分阶段控制Collider与碰撞检测

  • 预览阶段:保持待放置对象的Box Collider禁用,避免射线检测时打到自身导致位置偏移。如果需要提前检测是否与已放置对象重叠,可以给对象额外添加一个勾选Is Trigger的Collider(比如独立的Box Collider组件),用OnTriggerEnter/Stay判断重叠状态,提示用户是否可放置。
  • 放置确认阶段(比如点击鼠标左键):
    • 禁用触发Collider(如果使用了的话)
    • 启用原本的Box Collider
    • 若需要物理交互,添加Rigidbody并设置参数:
      • 勾选Is Kinematic(避免物理引擎自动推动对象,解决上浮问题)
      • 根据需求选择是否关闭Use Gravity

2. 优化射线检测,排除自身对象

如果不想额外加触发Collider,可以通过层掩码让射线忽略待放置对象,这样就能在预览时激活Box Collider:

  • 给待放置对象单独创建一个层(比如PlaceablePreview)
  • 修改射线检测逻辑,排除该层:
private LayerMask previewLayerMask;

private void Start()
{
    // 获取预览层的掩码并取反,让射线检测时忽略该层
    previewLayerMask = ~LayerMask.GetMask("PlaceablePreview");
}

private void MoveCurrentPlaceableHouseToMouse()
{
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    RaycastHit hitInfo;

    // 传入层掩码,确保射线只检测地面和已放置对象
    if (Physics.Raycast(ray, out hitInfo, Mathf.Infinity, previewLayerMask))
    {
        currentPlaceableHouse.transform.position = hitInfo.point;
        currentPlaceableHouse.transform.rotation = Quaternion.FromToRotation(Vector3.up, hitInfo.normal);
    }
}

3. 放置完成后的碰撞生效处理

添加放置确认的逻辑,确保碰撞组件正确激活:

private void Update()
{
    if (Input.GetMouseButtonDown(0) && currentPlaceableHouse != null)
    {
        // 启用Box Collider
        BoxCollider collider = currentPlaceableHouse.GetComponent<BoxCollider>();
        if (collider != null) collider.enabled = true;

        // 添加并配置Rigidbody(按需选择)
        Rigidbody rb = currentPlaceableHouse.GetComponent<Rigidbody>();
        if (rb == null) rb = currentPlaceableHouse.AddComponent<Rigidbody>();
        rb.isKinematic = true; // 静态碰撞设为true,需要物理交互设为false
        rb.useGravity = false; // 静态物体可关闭重力
        rb.freezeRotation = true; // 防止不必要的旋转

        // 完成放置,清空当前对象
        currentPlaceableHouse = null;
    }
}

如果仅需要静态碰撞(不需要物理交互),无需添加Rigidbody,只要确保Collider启用并勾选对象的Static选项即可。

4. 解决Rigidbody上浮问题

之前添加无重力Rigidbody后上浮,本质是对象Collider与地面/已放置对象的Collider重叠,物理引擎为分离碰撞体自动推动对象。解决方式:

  • 预览阶段用触发Collider检测重叠,禁止在重叠位置放置
  • 给Rigidbody设置Is Kinematic = true,让物理引擎不控制对象移动,但仍保留碰撞检测能力

内容的提问来源于stack exchange,提问作者unityfan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 04:10:06