为什么我的对象没有更新成相对于我的双手的位置?

编程语言 2026-07-12

我在使用一个 PickUpObject脚本,用来捡起物体。

我发现,当物体被拿着时,它并不能相对于myHands跟随我的手的位置。此外,你可以无限制地抛出物体。

更多信息:

  • 持有物体时,物体的位置不会更新为myHands.transform.position;
  • 另外,当按下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)
        {
            if (!Input.GetKey(KeyCode.E))
                Drop();
            if (Input.GetKey(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)
            {                
                if (Input.GetKey(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()
    {
        // Identical as Drop, but addforce
        if (!isHolding) return;

        // 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);
        }
    }

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

解决方案

粗略浏览后,我发现每次调用 Update 时,如果没有发生其他情况,你就会调用 TryPickupRaycast。此外,在抛掷时,没有任何迹象表明你已经停止握住对象(即使它是 SetActive)。有两点:

  • 我看不到调用代码,但似乎即使你 Throw 对象,在你松开 F 键的瞬间,它就可能被拾取。
  • Throw 的某处调用 Drop,或者将共享的“释放保持”代码重构为能同时从 DropThrow 调用。我猜这两个方法最终可能会调用同一个私有方法,只是传入的力值不同(0throwForce)。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章