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

Unity VR HDRP项目胶水系统实现问题及优化需求

Unity 2021.3.9f1 HDRP VR胶水系统问题与优化需求

我在Unity 2021.3.9f1版本的HDRP 3D VR项目中,想要实现一套胶水系统:当工具触碰物体时绘制胶水标记区域,并创建触发碰撞器,以便当可粘合物体进入该触发范围时应用关节逻辑。

以下是我当前编写的PaintTool代码:

public class PaintTool : MonoBehaviour
{
    public Color paintColor = Color.red;
    public float paintRadius = 1f;

    void OnCollisionEnter(Collision collision)
    {
        Debug.Log(collision.transform.gameObject.tag);
        if (collision.gameObject.tag == "Wood")
        {
            MeshFilter meshFilter = collision.gameObject.GetComponent<MeshFilter>();
            if (meshFilter == null)
            {
                meshFilter = collision.gameObject.GetComponentInChildren<MeshFilter>();
            }

            Renderer renderer = collision.gameObject.GetComponent<Renderer>();
            if (renderer == null)
            {
                renderer = collision.gameObject.GetComponentInChildren<Renderer>();
            }

            if (meshFilter != null && renderer != null && renderer.sharedMaterial != null)
            {
                Texture2D texture = renderer.material.mainTexture as Texture2D;
                Debug.Log("check 1");
                if (texture != null)
                {
                    Debug.Log("check 2");
                    ContactPoint contact = collision.contacts[0];
                    Vector3 point = contact.point;
                    Vector3 normal = contact.normal;

                    // Use a MeshCollider to perform the raycast
                    MeshCollider meshCollider = collision.gameObject.GetComponent<MeshCollider>();
                    if (meshCollider == null)
                    {
                        meshCollider = collision.gameObject.GetComponentInChildren<MeshCollider>();
                    }

                    RaycastHit hit;
                    if (meshCollider.Raycast(new Ray(point - normal * 1f, normal), out hit, Mathf.Infinity))
                    {
                        Debug.Log("check 3");
                        Vector2 pixelUV = hit.textureCoord;

                        int textureWidth = texture.width;
                        int textureHeight = texture.height;
                        int pixelX = Mathf.FloorToInt(pixelUV.x * textureWidth);
                        int pixelY = Mathf.FloorToInt(pixelUV.y * textureHeight);

                        Bounds paintedAreaBounds = new Bounds(hit.point, Vector3.one * paintRadius * 2);

                        for (int x = pixelX - Mathf.FloorToInt(paintRadius); x < pixelX + Mathf.FloorToInt(paintRadius); x++)
                        {
                            for (int y = pixelY - Mathf.FloorToInt(paintRadius); y < pixelY + Mathf.FloorToInt(paintRadius); y++)
                            {
                                if (x >= 0 && x < textureWidth && y >= 0 && y < textureHeight)
                                {
                                    Color currentColor = texture.GetPixel(x, y);
                                    Color newColor = Color.Lerp(currentColor, paintColor, paintColor.a);
                                    texture.SetPixel(x, y, newColor);

                                    // Expand the bounds to include this pixel
                                    paintedAreaBounds.Encapsulate(new Vector3(x, y, 0));
                                }
                            }
                        }

                        texture.Apply();

                        // Create a trigger collider that matches the painted area
                        BoxCollider triggerCollider = collision.gameObject.AddComponent<BoxCollider>();
                        triggerCollider.isTrigger = true;
                        triggerCollider.center = paintedAreaBounds.center - collision.gameObject.transform.position;
                        triggerCollider.size = paintedAreaBounds.size;
                    }
                }
            }
        }
    }
}

该代码可运行,但未达到预期效果,需要改进以下几点以实现可用功能:

  • 触发碰撞器尺寸过大
  • 仅在初始接触点绘制,无法拖拽绘制连续区域
  • 未考虑物体不同区域的多次绘制,每个绘制区域应对应独立的触发碰撞器

注:此处的“绘制”指的是标记胶水区域。我曾尝试通过生成碰撞物体来创建关节,但为避免关节过于松弛需施加较大力,导致关节过多时物体出现异常。现寻求优化现有方案或替代实现方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 12:07:00