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

如何在Unity中实现类似《半条命2》《传送门》的物体拾取功能

Unity传送门风格物体抓取功能修复方案

现有实现的问题

你当前遇到的两个典型异常效果如下:
全局抓取异常
模型变形异常
核心原因分为三点:

  • 挂载逻辑错误:你将抓取脚本挂在了全局Destination锚点对象上,触发逻辑时操作的是锚点本身而非目标抓取物体,导致所有绑定了锚点的物体同时响应
  • 无瞄准检测:没有对玩家准星指向的物体做射线检测,按下F键直接全局触发逻辑,没有筛选目标
  • 缩放继承异常:直接将抓取物体设为锚点的子物体,当锚点或上层节点有非1缩放时,子物体会继承缩放导致模型变形

修复实现步骤

1. 前置准备

  • 删除挂在Destination空对象上的原有脚本
  • 给所有可抓取物体添加Pickable自定义标签
  • 确保所有可抓取物体都带有Rigidbody组件
  • 将Destination空对象设为玩家主相机的子物体,放在相机前方2-3米位置,锚点和所有上层节点的缩放全部设为(1,1,1)

2. 修改后的脚本

这个脚本挂在玩家主相机上即可:

using UnityEngine;

public class PickUp : MonoBehaviour
{
    // 抓取物体的放置锚点,拖拽你的Destination对象到这里
    public Transform holdAnchor;
    // 最大可抓取距离
    public float maxPickDistance = 3.5f;
    // 当前持有的物体刚体
    private Rigidbody heldObjectRb;

    private void Update()
    {
        // 按F键切换抓取/放下状态
        if (Input.GetKeyDown(KeyCode.F))
        {
            if (heldObjectRb == null)
            {
                TryPickUp();
            }
            else
            {
                DropObject();
            }
        }

        // 抓取状态下持续将物体移动到锚点位置
        if (heldObjectRb != null)
        {
            heldObjectRb.MovePosition(holdAnchor.position);
        }
    }

    // 尝试抓取准星指向的可拾取物体
    private void TryPickUp()
    {
        Ray pickRay = new Ray(transform.position, transform.forward);
        if (Physics.Raycast(pickRay, out RaycastHit hitInfo, maxPickDistance))
        {
            // 仅对带Pickable标签且有刚体的物体生效
            if (hitInfo.collider.CompareTag("Pickable") && hitInfo.rigidbody != null)
            {
                heldObjectRb = hitInfo.rigidbody;
                heldObjectRb.useGravity = false;
                heldObjectRb.freezeRotation = true;
            }
        }
    }

    // 放下当前持有的物体
    private void DropObject()
    {
        heldObjectRb.useGravity = true;
        heldObjectRb.freezeRotation = false;
        // 给物体一个向前的初速度,模拟投掷效果
        heldObjectRb.velocity = transform.forward * 6f;
        heldObjectRb = null;
    }
}

3. 参数配置

  • 将相机下挂的Destination对象拖拽到脚本的holdAnchor字段
  • 可根据需求调整maxPickDistance参数修改最大抓取距离
  • 如果抓取时物体有明显晃动,可将可抓取物体刚体组件的Drag参数调整到10左右

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 22:06:03