繁体   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