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

Unity 3D中点击地球模型获取点击位置颜色的实现疑问

Unity 3D点击地球模型获取点击位置颜色的解决方案

要解决相机与地球模型有距离时无法识别点击位置颜色的问题,核心是通过射线检测定位碰撞点,再将碰撞点转换为模型纹理的UV坐标,最终采样纹理获取颜色。具体步骤如下:

1. 给地球模型添加碰撞体

首先确保地球模型有能被射线检测到的碰撞体:

  • 若地球是标准球体,添加Sphere Collider即可,检测效率更高;
  • 若地球是高精度自定义模型,添加Mesh Collider(静态模型无需勾选Convex,动态模型需勾选),保证射线能精准命中模型表面。

2. 射线检测获取碰撞信息

编写脚本处理鼠标点击事件,通过相机发射射线定位地球表面的碰撞点:

using UnityEngine;

public class EarthClickHandler : MonoBehaviour
{
    public Texture2D earthTexture; // 拖拽地球的纹理到此处
    private Renderer earthRenderer;

    void Start()
    {
        // 获取地球模型的Renderer组件(提前确认模型有MeshRenderer/SkinnedMeshRenderer)
        earthRenderer = GameObject.Find("Earth").GetComponent<Renderer>();
        
        // 检查纹理是否开启可读权限
        if (!earthTexture.isReadable)
        {
            Debug.LogError("请在地球纹理的导入设置中勾选Read/Write Enabled");
        }
    }

    void Update()
    {
        // 监听鼠标左键点击
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out RaycastHit hit))
            {
                // 判断是否点击到地球模型
                if (hit.collider.gameObject == earthRenderer.gameObject)
                {
                    Color clickedColor = GetClickedColor(hit);
                    Debug.Log("点击位置颜色:" + clickedColor);
                    // 此处可根据颜色执行后续交互逻辑,比如判断是否为目标颜色区域
                }
            }
        }
    }

3. 转换坐标并采样纹理颜色

实现GetClickedColor方法,将碰撞点的世界坐标转换为纹理UV坐标,最终采样获取颜色:

private Color GetClickedColor(RaycastHit hit)
    {
        Mesh mesh = earthRenderer.GetComponent<MeshFilter>().mesh;
        // 获取碰撞点所在的三角形索引
        int triangleIndex = hit.triangleIndex;
        // 提取三角形的三个顶点索引
        int[] triangles = mesh.triangles;
        int v1 = triangles[triangleIndex * 3];
        int v2 = triangles[triangleIndex * 3 + 1];
        int v3 = triangles[triangleIndex * 3 + 2];

        // 获取三个顶点对应的UV坐标
        Vector2[] uvs = mesh.uv;
        Vector2 uv1 = uvs[v1];
        Vector2 uv2 = uvs[v2];
        Vector2 uv3 = uvs[v3];

        // 通过重心坐标计算碰撞点对应的插值UV
        Vector3 barycentric = hit.barycentricCoordinate;
        Vector2 targetUV = uv1 * barycentric.x + uv2 * barycentric.y + uv3 * barycentric.z;

        // 采样纹理颜色(GetPixelBilinear适配纹理缩放后的精度需求)
        return earthTexture.GetPixelBilinear(targetUV.x, targetUV.y);
    }
}

关键注意事项

  • 纹理必须开启Read/Write Enabled:在Project窗口选中纹理,Inspector面板的Import Settings中勾选该选项,点击Apply生效;
  • 若地球使用SkinnedMeshRenderer,需替换为skinnedMeshRenderer.sharedMesh获取网格数据;
  • 确保模型缩放与碰撞体缩放一致,避免射线检测出现偏差。

内容的提问来源于stack exchange,提问作者이세윤

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 14:03:22