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

Unity中使用C#获取3D物体任意点击位置相对于枢轴点的坐标方法

嘿,这个需求其实挺常见的,我来一步步给你捋清楚怎么实现~

实现点击3D物体获取相对枢轴坐标的方法

核心思路很明确:先通过射线检测定位点击在物体表面的世界坐标,再把这个世界坐标转换为物体局部空间下的坐标——而局部空间坐标,就是相对于物体枢轴点的位置。

步骤1:射线检测命中物体表面

不管你用Unity还是Unreal这类主流引擎,第一步都是从屏幕点击位置发射射线,确认是否命中目标3D物体。这是基础前提,只有拿到点击的世界位置,才能进行后续转换。

Unity 示例代码:

// 先定义你的目标物体
public GameObject targetObject;

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        // 从相机向鼠标位置发射射线
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out RaycastHit hitInfo))
        {
            // 确认命中的是我们要检测的物体
            if (hitInfo.collider.gameObject == targetObject)
            {
                Vector3 worldClickPos = hitInfo.point;
                // 进入下一步转换坐标
                GetLocalPosRelativeToPivot(worldClickPos);
            }
        }
    }
}

Unreal 示例代码:

// 先定义你的目标Actor
UPROPERTY(EditAnywhere)
AActor* TargetActor;

void AYourActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    if (GetWorld()->GetFirstPlayerController()->WasInputKeyJustPressed(EKeys::LeftMouseButton))
    {
        FHitResult HitResult;
        bool bIsHit = GetWorld()->GetFirstPlayerController()->GetHitResultUnderCursor(ECC_Visibility, false, HitResult);
        
        if (bIsHit && HitResult.GetActor() == TargetActor)
        {
            FVector WorldClickPos = HitResult.Location;
            // 进入下一步转换坐标
            GetLocalPosRelativeToPivot(WorldClickPos);
        }
    }
}

步骤2:将世界坐标转换为局部坐标

这一步是关键!引擎都提供了直接的转换方法,能把世界坐标转换成以物体枢轴为原点的局部坐标:

Unity 转换方法:

用Transform.InverseTransformPoint(),它会自动帮你完成空间转换:

void GetLocalPosRelativeToPivot(Vector3 worldPos)
{
    Vector3 localPos = targetObject.transform.InverseTransformPoint(worldPos);
    // 这里的localPos就是你要的相对枢轴的X/Y/Z坐标
    Debug.Log($"相对枢轴坐标:({localPos.x:F1}, {localPos.y:F1}, {localPos.z:F1})");
}

Unreal 转换方法:

用GetTransform().InverseTransformPosition(),效果完全一致:

void AYourActor::GetLocalPosRelativeToPivot(FVector WorldPos)
{
    FVector LocalPos = TargetActor->GetTransform().InverseTransformPosition(WorldPos);
    UE_LOG(LogTemp, Log, TEXT("相对枢轴坐标:(%.1f, %.1f, %.1f)"), LocalPos.X, LocalPos.Y, LocalPos.Z);
}

匹配你的示例场景

比如你提到点击中心返回(0,50,0),说明你的物体枢轴点不在模型中心,而是在模型底部(中心Y轴偏移了50)。用上面的方法转换后,得到的局部坐标会严格匹配你的需求——因为转换逻辑就是以物体的枢轴点作为原点计算的。

注意事项

  • 确保目标3D物体添加了碰撞体(Collider/Collision Component),否则射线检测会直接忽略它;复杂模型建议用网格碰撞体或凸碰撞体保证检测准确性。
  • 多测试几个特征点(比如你说的左上角(0,0,0)),验证转换结果是否符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 22:48:11