Unity中如何将碰撞点转换为Texture2D的像素点?
如何将射线检测得到的3D碰撞点转换为Texture2D的像素坐标?
首先先修正你代码里的一个明显问题:每次调用Draw都新建Texture2D会完全覆盖之前的绘制内容,应该把Texture2D作为脚本的成员变量,在初始化时创建一次。
接下来解决3D坐标转纹理像素坐标的问题,核心思路是把世界空间的碰撞点转换为绘制平面的局部空间坐标,再归一化后映射到纹理的像素范围,步骤如下:
将世界碰撞点转为平面局部坐标
使用transform.InverseTransformPoint(hit.point)把射线检测到的世界坐标,转换为挂载该脚本的平面物体的局部坐标(假设你的绘制平面是Quad/Plane,脚本挂在这个物体上)。归一化局部坐标到[0,1]范围
默认的Quad/Plane在局部空间的尺寸是1x1(比如Quad的局部x范围是-0.5到0.5,z范围也是-0.5到0.5),所以把局部坐标的x和z(对应平面的横向和纵向)加上0.5,就能得到0到1之间的归一化值。映射到纹理像素坐标
用归一化值分别乘以纹理的宽度和高度,再取整就得到Texture2D需要的(x,y)像素坐标。
下面是修改后的完整代码:
using UnityEngine; public class DrawOnPlane : MonoBehaviour { // 定义纹理尺寸和绘制颜色 public int textureSize = 128; public Color drawColor = Color.black; private Texture2D drawTexture; void Start() { // 初始化纹理,只执行一次 drawTexture = new Texture2D(textureSize, textureSize); // 初始化纹理为白色(可选,根据你的需求调整) Color[] clearColor = new Color[textureSize * textureSize]; for (int i = 0; i < clearColor.Length; i++) { clearColor[i] = Color.white; } drawTexture.SetPixels(clearColor); drawTexture.Apply(); // 给物体的Renderer赋值纹理 GetComponent<Renderer>().material.mainTexture = drawTexture; } void Update() { if (Input.GetMouseButton(0)) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out RaycastHit hit)) { // 只处理当前平面的碰撞(避免误触其他物体) if (hit.transform == transform) { Draw(hit.point); } } } } void Draw(Vector3 worldPos) { // 1. 转换为局部坐标 Vector3 localPos = transform.InverseTransformPoint(worldPos); // 2. 归一化到[0,1]范围(这里假设平面是XZ平面,Y轴向上) float normalizedX = localPos.x + 0.5f; float normalizedY = localPos.z + 0.5f; // 3. 转换为像素坐标,取整 int pixelX = Mathf.RoundToInt(normalizedX * drawTexture.width); int pixelY = Mathf.RoundToInt(normalizedY * drawTexture.height); // 确保像素坐标在纹理范围内(防止超出边界报错) pixelX = Mathf.Clamp(pixelX, 0, drawTexture.width - 1); pixelY = Mathf.Clamp(pixelY, 0, drawTexture.height - 1); // 设置像素颜色并应用 drawTexture.SetPixel(pixelX, pixelY, drawColor); drawTexture.Apply(); } }
注意事项:
- 如果你的绘制平面不是默认的XZ朝向(比如是XY平面),需要调整局部坐标的轴,比如用localPos.y代替z来计算normalizedY。
- 添加了
hit.transform == transform的判断,确保只在当前平面上绘制,不会误操作场景中的其他碰撞体。 - 初始化纹理时填充了白色背景,你可以根据需求改成其他颜色。
内容的提问来源于stack exchange,提问作者MUSA ZENBİLCİ
相关产品推荐
相关产品推荐

