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

Unity中点击Plane控件无法输出Position和Distance问题求助

问题:点击Plane控件无法在Console输出位置与距离信息

我想要点击场景中的Plane控件时,在Console里获取它的Position(位置)和Distance(距离)信息,但把以下两段C#脚本挂载到Plane对象后,功能始终无法正常运行。

原Distance脚本

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.EventSystems;

public class Distance : MonoBehaviour, IPointerDownHandler
{
    public GameObject Camera; 
    public GameObject Object; 
    public float Distance_;

    void Start()
    {

    }

    public void OnPointerDown(PointerEventData eventData)
    {
        Distance_ = Vector3.Distance(Camera.transform.position, Object.transform.position);  

        Debug.Log("Distance: " + Distance_); 
    }
}

原Position脚本

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;

public class Position : MonoBehaviour, IPointerDownHandler
{
    public Vector3 worldPosition;
    Plane plane = new Plane(Vector3.up, 0);
    public void OnPointerDown(PointerEventData eventData)
    {
        float distance;
        Ray ray = Camera.main.ScreenPointToRay(eventData.position);
        if (plane.Raycast(ray, out distance))
        {
            worldPosition = ray.GetPoint(distance);

            Debug.Log("Position: " + worldPosition);

            //print("Position: " + worldPosition);
        }
    }
}

问题排查与修复方案

1. 基础交互组件检查

Plane要能响应点击,必须满足以下条件:

  • 场景中存在全局的EventSystem和StandaloneInputModule组件(右键UI -> EventSystem可自动创建)
  • Plane对象添加Mesh Collider(3D场景)或确保Rect Transform启用碰撞(UI Plane),无碰撞体则射线无法检测到点击
  • 相机添加Physics Raycaster组件(3D场景)或Graphic Raycaster(UI场景)

2. 修复Distance脚本

原脚本存在空引用风险(Camera和Object未赋值),且逻辑不符合“点击Plane时获取距离”的需求,修复后脚本:

using UnityEngine;
using UnityEngine.EventSystems;

public class Distance : MonoBehaviour, IPointerDownHandler
{
    private Camera mainCamera;

    void Start()
    {
        mainCamera = Camera.main;
        if (mainCamera == null)
        {
            Debug.LogError("场景中未找到标记为MainCamera的相机!");
        }
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        if (mainCamera == null) return;

        // 计算相机到Plane自身的距离
        float planeToCameraDistance = Vector3.Distance(mainCamera.transform.position, transform.position);
        Debug.Log($"Plane到相机的距离: {planeToCameraDistance}");

        // 计算点击点到相机的距离(可选)
        Ray ray = mainCamera.ScreenPointToRay(eventData.position);
        if (Physics.Raycast(ray, out RaycastHit hit) && hit.collider.gameObject == gameObject)
        {
            float clickPointToCameraDistance = Vector3.Distance(mainCamera.transform.position, hit.point);
            Debug.Log($"点击点到相机的距离: {clickPointToCameraDistance}");
        }
    }
}

3. 修复Position脚本

原脚本用自定义Plane代替场景中的Plane控件,导致检测逻辑错误,修复后脚本:

using UnityEngine;
using UnityEngine.EventSystems;

public class Position : MonoBehaviour, IPointerDownHandler
{
    private Camera mainCamera;

    void Start()
    {
        mainCamera = Camera.main;
        if (mainCamera == null)
        {
            Debug.LogError("场景中未找到标记为MainCamera的相机!");
        }
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        if (mainCamera == null) return;

        Ray ray = mainCamera.ScreenPointToRay(eventData.position);
        // 检测点击到当前Plane的碰撞体,获取精确点击位置
        if (Physics.Raycast(ray, out RaycastHit hit) && hit.collider.gameObject == gameObject)
        {
            Vector3 clickWorldPosition = hit.point;
            Debug.Log($"点击的世界位置: {clickWorldPosition}");
            Debug.Log($"Plane自身的世界位置: {transform.position}");
        }
    }
}

4. 合并功能(推荐)

将两个功能合并到一个脚本,减少冗余:

using UnityEngine;
using UnityEngine.EventSystems;

public class PlaneClickInfo : MonoBehaviour, IPointerDownHandler
{
    private Camera mainCamera;

    void Start()
    {
        mainCamera = Camera.main;
        if (mainCamera == null)
        {
            Debug.LogError("场景中未找到标记为MainCamera的相机!");
        }
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        if (mainCamera == null) return;

        Ray ray = mainCamera.ScreenPointToRay(eventData.position);
        if (Physics.Raycast(ray, out RaycastHit hit) && hit.collider.gameObject == gameObject)
        {
            // 输出点击点位置
            Debug.Log($"点击的世界位置: {hit.point}");
            // 输出Plane自身位置
            Debug.Log($"Plane自身位置: {transform.position}");
            // 输出相机到点击点的距离
            Debug.Log($"相机到点击点的距离: {Vector3.Distance(mainCamera.transform.position, hit.point)}");
            // 输出相机到Plane的距离
            Debug.Log($"相机到Plane的距离: {Vector3.Distance(mainCamera.transform.position, transform.position)}");
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 09:36:20