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

Unity拾取物体脚本故障修复咨询:持有时物体不跟随手部、可无限触发投掷

Unity拾取物体脚本故障修复咨询:持有时物体不跟随手部、可无限触发投掷

嘿,我来帮你搞定这两个问题!咱们先拆解一下问题根源,再给你修复后的完整代码:

问题1:持有时物体不跟随手部

你的核心问题出在按键检测逻辑错误:原代码用了Input.GetKey(KeyCode.E)(按住E键才生效),而且在持有状态下,只要没按住E就会自动调用Drop()。这意味着你必须一直按住E才能拿住物体,松开就立刻掉落,自然没法让物体稳定跟随手部。

问题2:可无限触发投掷

原Throw()函数没有重置持有状态(isHolding没设为false,也没清空heldObject和heldRb),所以每次按F都会重复执行投掷逻辑,给物体持续加力,导致“无限扔”的情况。


修复后的完整代码

我把关键逻辑都调整好了,标注了修改点:

using TMPro;
using Unity.VisualScripting;
using UnityEngine;
using static UnityEngine.GraphicsBuffer;

public class PickUpObject : MonoBehaviour
{
    [Header("Pickup")]
    public Transform hand;
    public float pickupDistance = 3f;
    public LayerMask pickupMask;

    [Header("UI")]
    [Header("Throw")]
    public float throwForce = 8f; // Throw force
    public ForceMode throwForceMode = ForceMode.VelocityChange; // Add force immediately
    GameObject heldObject;
    Rigidbody heldRb;
    bool isHolding;

    void Update()
    {      
        // If holding something
        if (isHolding)
        {
            // 修改:用GetKeyDown(按下瞬间)触发放下,而不是松开E就自动放下
            if (Input.GetKeyDown(KeyCode.E))
                Drop();
            // 修改:用GetKeyDown确保投掷只触发一次,不是按住F就一直扔
            if (Input.GetKeyDown(KeyCode.F))
                Throw();
           
            return;
        }

        TryPickupRaycast();
    }

    void TryPickupRaycast()
    {
        RaycastHit hit;

        if (Physics.Raycast(
            Camera.main.transform.position,
            Camera.main.transform.forward,
            out hit,
            pickupDistance,
            pickupMask))
        {
            Rigidbody rb = hit.collider.GetComponent<Rigidbody>();

            if (rb != null)
            {                
                // 修改:用GetKeyDown(按下瞬间)触发拾取,不是按住E才拾取
                if (Input.GetKeyDown(KeyCode.E))
                {
                    PickUp(hit.collider.gameObject, rb);
                }
            }           
        }
    }


    void PickUp(GameObject obj, Rigidbody rb)
    {
        heldObject = obj;
        heldRb = rb;
        isHolding = true;

        heldRb.isKinematic = true;

        Collider col = obj.GetComponent<Collider>();
        if (col) col.enabled = false;

        obj.transform.SetParent(hand);
        obj.transform.localPosition = Vector3.zero;
        obj.transform.localRotation = Quaternion.identity;
    }

    public void Drop()
    {
        if (!isHolding) return;

        isHolding = false;

        heldRb.isKinematic = false;

        Collider col = heldObject.GetComponent<Collider>();
        if (col) col.enabled = true;

        heldObject.transform.SetParent(null);

        heldObject = null;
        heldRb = null;
    }

    void Throw()
    {
        if (!isHolding) return;

        // 修改:扔出前先启用碰撞体
        Collider col = heldObject.GetComponent<Collider>();
        if (col) col.enabled = true;

        // Unparent
        heldObject.transform.SetParent(null);

        // Reestablish the New Rigidbody Targetting
        if (heldObject != null) heldObject.SetActive(true);

        if (heldRb != null)
        {
            heldRb.isKinematic = false;

            // Throw force: at myHands.position.forward
            Vector3 dir = hand.forward;

            // restart speed and then addforce
            heldRb.linearVelocity = Vector3.zero;
            heldRb.angularVelocity = Vector3.zero;
            heldRb.AddForce(dir * throwForce, throwForceMode);
        }

        // 修改:清空持有状态,防止重复触发投掷
        isHolding = false;
        heldObject = null;
        heldRb = null;
    }

    // Used by SceneTransform
    public bool IsHolding() => isHolding;
    public GameObject GetHeldObject() => heldObject;
}

修复要点说明

  1. 按键逻辑修正:把所有Input.GetKey改成Input.GetKeyDown,这样拾取、放下、投掷都是按下按键瞬间触发一次,符合正常操作逻辑。
  2. 投掷状态重置:在Throw()函数末尾添加了持有状态的清空,确保扔出后不会重复执行投掷逻辑。
  3. 碰撞体管理:在投掷时主动启用碰撞体,和Drop()保持一致,避免物体扔出后无法碰撞。

这样修改后,物体持有时会稳定跟随手部,按F只会投掷一次,不会无限触发啦!

备注:内容来源于stack exchange,提问作者idiotStackOverflow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 18:04:33