簡體   English   中英

如何准確獲取相機直接指向的物體?

[英]How to accurately get the objects that the camera is directly pointed to?

我正在嘗試在我的游戲中拾取對象。 因此,用戶直接查看的 object 可以通過單擊按鈕來獲取。 我有LookObject ,它是一個gameObejct ,用於存儲我當前正在查看的對象。 我在這里面臨的問題是LookObject沒有准確地顯示我正在查看的對象。 請看這張圖片。

如圖所示,標線並不完全位於立方體上,但外觀 object 顯示的是立方體。 我怎樣才能使它准確?

 [Header("InteractableInfo")]
public float sphereCastRadius = 0.5f;
public int interactableLayerIndex;
private Vector3 raycastPos;
public GameObject lookObject; 
private PhysicsObjects physicsObject;
private Camera mainCamera;
public GameObject winUI;
private InteractiveObjects interactiveObjects;
  void Update()
    {
        //Here we check if we're currently looking at an interactable object
        raycastPos = mainCamera.ScreenToWorldPoint(new Vector3(Screen.width / 2, Screen.height / 2, 0));
        RaycastHit hit;
        if (Physics.SphereCast(raycastPos, sphereCastRadius, mainCamera.transform.forward, out hit, maxDistance, 1 << interactableLayerIndex))
        {

            lookObject = hit.collider.transform.gameObject;
           
        }
        Physics.Raycast(mainCamera.transform.position, mainCamera.transform.forward, out hit, maxDistance);
        if (hit.transform)
        {
            interactiveObjects = hit.transform.GetComponent<InteractiveObjects>();
        }
        else
        {
            lookObject = null;
            interactiveObjects = null;

        }
        //if we press the button of choice
        if (Input.GetKeyDown(KeyCode.Space))
        {
            //and we're not holding anything
            if (currentlyPickedUpObject == null)
            {
                //and we are looking an interactable object
                if (lookObject != null )
                {
                    PickUpObject();     }
}
}
}

這是立方體inspector

立方體和所有其他可交互對象都有這個腳本:

public class PhysicsObjects : MonoBehaviour
{
    public float waitOnPickup = 0.2f;
    public float breakForce = 35f;
    [HideInInspector] public bool pickedUp = false;
    [HideInInspector] public PlayerInteractions playerInteractions;


    private void OnCollisionEnter(Collision collision)
    {
        if (pickedUp)
        {
            if (collision.relativeVelocity.magnitude > breakForce)
            {
                playerInteractions.BreakConnection();
            }

        }
    }

    //this is used to prevent the connection from breaking when you just picked up the object as it sometimes fires a collision with the ground or whatever it is touching
    public IEnumerator PickUp()
    {
        yield return new WaitForSecondsRealtime(waitOnPickup);
        pickedUp = true;

    }
}

你在做

if (Physics.SphereCast(raycastPos, sphereCastRadius, mainCamera.transform.forward, out hit, maxDistance, 1 << interactableLayerIndex))
{
    lookObject = hit.collider.transform.gameObject; 
}

半徑0.5米!

然后接下來你做

 Physics.Raycast(mainCamera.transform.position, mainCamera.transform.forward, out hit, maxDistance);

沒有任何圖層過濾器,因此您會碰到地板。

所以檢查

if (hit.transform)
{
    interactiveObjects = hit.transform.GetComponent<InteractiveObjects>();
}
else
{
    lookObject = null;
    interactiveObjects = null;
}

進入if情況,即使第二個演員的hit.transform與第一個演員不同。


我真的不明白您為什么首先要進行兩次演員表。 您可能更願意簡單地堅持

if (Physics.SphereCast(mainCamera.ViewportPointToRay(Vector2.one * 0.5f), sphereCastRadius, mainCamera.transform.forward, out var hit, maxDistance, 1 << interactableLayerIndex))
// or if you don't want to use a sphere cast anyway
//if(Physics.Raycast(mainCamera.ViewportPointToRay(Vector2.one * 0.5f), maxDistance, 1 << interactableLayerIndex))
{
    var lookObject = hit.collider.gameObject;
       
    if(lookObject.TryGetComponent<InteractiveObjects>(out var interactiveObject))
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            //and we're not holding anything
            if (!currentlyPickedUpObject)
            {
                // whatever happens in here
                PickUpObject(interactiveObject);     
            }
        }
    }
}

並且只需使用較小的半徑進行球體投射,或者如果您不想使用半徑,則直接使用簡單的 RayCast。


一般來說,我還建議寧願使用

public LayerMask interactableLayers;

然后直接使用interactableLayers而不是1 << interactableLayerIndex

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM