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

Unity:如何从球体与平面的碰撞点发射射线?

解决方案:从球体与平面的碰撞接触点映射地形生成预制体

原代码的核心问题在于:使用OnTriggerEnter无法获取真实的碰撞接触点数据,且通过transform.forward发射射线只能固定取球体正前方的点,而非球体与平面实际接触的位置。以下是修正后的实现方案:

关键修正点

  • 改用OnCollisionEnter回调(而非OnTriggerEnter),该回调能提供完整的碰撞接触信息
  • 直接从collision.contacts中提取球体与平面的碰撞点,而非通过固定方向射线模拟
  • 将世界空间的碰撞点转换为平面的纹理UV坐标,再映射到地形相机的视口射线

完整代码实现

// 确保球体和平面的Collider都未勾选Is Trigger,否则无法触发OnCollisionEnter
private void OnCollisionEnter(Collision collision)
{
    if (collision.gameObject.CompareTag("Plane"))
    {
        // 遍历所有碰撞接触点(球体碰平面通常只有1个点,遍历兼容多接触场景)
        foreach (ContactPoint contact in collision.contacts)
        {
            // 将世界空间的碰撞点转换为平面的局部空间坐标
            Vector3 localPoint = collision.transform.InverseTransformPoint(contact.point);
            
            // 计算平面的纹理UV坐标:示例假设平面是XY平面(局部Z轴向上),UV对应X/Z轴
            // 若你的平面是XZ平面(Y轴向上),则替换为localPoint.x和localPoint.z
            Vector2 uv = new Vector2(
                (localPoint.x / collision.transform.localScale.x + 0.5f),
                (localPoint.z / collision.transform.localScale.z + 0.5f)
            );
            
            // 确保UV在0-1范围内,避免视口射线越界
            uv = Vector2.Clamp01(uv);
            
            // 通过地形相机发射视口射线到地形
            Ray terrainRay = terrainCamera.ViewportPointToRay(uv);
            if (Physics.Raycast(terrainRay, out RaycastHit terrainHit))
            {
                StartCoroutine(SpawnObjectOnTerrain(terrainHit.point));
            }
            
            // 若仅需处理第一个接触点,可添加break跳出循环
            // break;
        }
    }
}

注意事项

  1. Collider设置:必须取消球体和平面的Is Trigger勾选,OnCollisionEnter才会触发并生成接触点数据
  2. 平面朝向适配:根据你使用的平面朝向调整UV计算的轴,比如XZ平面(Y轴向上)需用localPoint.x和localPoint.z
  3. 平面缩放处理:如果平面有非均匀缩放,必须将局部坐标除以对应轴的缩放值,才能得到正确的UV范围
  4. 多接触点处理:如果球体滚动时会产生多个接触点,可根据需求选择处理第一个点或所有点

效果对比

当前与期望效果对比
上方:原方案仅从球体正前方发射射线;下方:修正后从实际碰撞接触点发射射线

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 06:55:32