与同一图层上的对象碰撞时,被抓取的对象不会被光线投射掉落



我有第一人称玩家可以抓住和携带的物体。光线投射仅检查所有可以拾取的对象都在的一个图层上。

如果物体撞到不在同一层上的物体,则被保留的对象将被丢弃,因为光线不再击中被抓取的物体。这是预期行为。

但是,如果抓取的对象撞到同一图层上的对象,则不会丢弃该对象。我相信这是因为光线继续记录图层上的对象仍然被选中。

如何设置它,以便光线投射知道它已切换对象,并删除当前对象?

任何帮助都非常感谢!

下面是正在发生的事情的示例:

https://reddit.com/link/cgfyg0/video/5zk5ylbh0wb31/player

以下是控制玩家光线投射以检查是否可以抓取对象的代码:

public class PlayerPickUp : MonoBehaviour
{
    // Public variables
    public float rayLength;
    public bool objectSelected;
    // Private variables
    Camera camera;
    RaycastHit hit;
    GameObject hitObject;
    // Start is called before the first frame update
    void Start()
    {
    }
    // Update is called once per frame
    void Update()
    {
        // Set layerMask as layer 10
        int layerMask = 1 << 10;
        // Create ray and check for object hit
        if( Physics.Raycast(transform.position, transform.TransformDirection( Vector3.forward ), out hit, rayLength, layerMask ) )
        {   
            // Set objectSelected to true
            objectSelected = true;
            // Set hit object as hitObject
            hitObject = hit.collider.gameObject;
            // Set hitObject's selectedByPlayer var to true
            hitObject.GetComponent<AnimalGrab>().selectedByPlayer = true;
            // Draw debug line
            Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * hit.distance, Color.blue);
        }
        // Object no longer being selected
        else if( objectSelected )
        {
            // Set objectSelected to false
            objectSelected = false;
            // Set hitObject's selectedByPlayer var to false
            hitObject.GetComponent<AnimalGrab>().selectedByPlayer = false;
        } 
        // Ray has not hit anything
        else {
            // Sit hit object as empty
            hitObject = null;
            // Draw debug line
            Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * rayLength, Color.yellow);
        }
    }
}

下面是控制要抓取的对象的代码:

public class ObjectGrab : MonoBehaviour
{
    // Public variables
    public bool beingHeld;
    public bool selectedByPlayer;
    public GameObject selfObject;
    public GameObject tempParentObject;
    public GameObject playerObject;
    // Private variables
    float throwForce;
    float lookSpeed;
    float targetDistance;
    Vector3 selfPosition;
    Rigidbody rb;
    float selfDistance;
    // Start is called before the first frame update
    void Start()
    {
        // Assign rigidbody component
        rb = selfObject.GetComponent<Rigidbody>();
        // Set beingHeld as false
        beingHeld = false;
        // Set initial throwForce
        throwForce = 1000f;
        // Set initial lookSpeed
        lookSpeed = 10f;
    }
    // Update is called once per frame
    void Update()
    {
        // Calculate distance from parent object
        selfDistance = Vector3.Distance( selfObject.transform.position, tempParentObject.transform.position );
        // If being held
        if( beingHeld == true )
        {
        // Set velocity to 0
        rb.velocity = Vector3.zero;
        rb.angularVelocity = Vector3.zero;
        // Set as child of GrabPoint
        selfObject.transform.SetParent(tempParentObject.transform);
            // ROTATION
            //Distance between target and the actual rotating object
            Vector3 targetDistance = playerObject.transform.position - transform.position;  
            // Calculate the Quaternion for the rotation
            Quaternion rot = Quaternion.Slerp( transform.rotation, Quaternion.LookRotation( targetDistance ), lookSpeed * Time.deltaTime );
            //Apply the rotation 
            transform.rotation = rot; 
            // put 0 on the axis you do not want for the rotation object to rotate
            transform.eulerAngles = new Vector3( 0, transform.eulerAngles.y, 0 ); 
            // THROWING
            // If right click pressed
            if( Input.GetMouseButtonDown( 1 ) )
            {
                // Add force to self
                rb.AddForce( tempParentObject.transform.forward * throwForce );
                // Set beingHeld as false
            beingHeld = false;
            }
        }
        // If not being held
        else
        {
            selfPosition = selfObject.transform.position;
            selfObject.transform.SetParent( null );
            rb.useGravity = true;
            selfObject.transform.position = selfPosition;
        }
        // If not being selected by player
        if( selectedByPlayer == false )
        {
            // Set beingHeld as false
            beingHeld = false;
        }
    }
    // Mouse Down
    void OnMouseDown()
    {
        if( selectedByPlayer == true )
        {
            // Set beingHeld as true
        beingHeld = true;
            // Disable gravity
        selfObject.GetComponent<Rigidbody>().useGravity = false;
            // Enable collision detection
        selfObject.GetComponent<Rigidbody>().detectCollisions = true;
        }
    }
    // Mouse Up
    void OnMouseUp()
    {
        // Set beingHeld as false
        beingHeld = false;
    }
}

在更新函数的第一个 if 中:

if( Physics.Raycast[...])

您可以执行另一个检查来测试命中对象是否像这样更改:

if(hit.collider.gameObject != hitObject)
{
    // The object changed
}

然后在那里处理对象更改。

最新更新