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
相关产品推荐
相关产品推荐

