如何使用 Raycast 显示文本?

How to show text using Raycast?

基本上我想在这里做的是当玩家靠近门时显示一条文字说“门被锁上了!”,我希望只有当玩家在门前时才显示文字当他不看门或离门较远时就消失了。 我尝试了以下代码:

[SerializeField] private float maxDistance = 2f;
 void Update()
    {
        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;
            if (hit.collider.gameObject.tag == "Door")
            {
                textUI.SetActive(true);
                centerUI.SetActive(false);
            }
            else
            {
                textUI.SetActive(false);
                centerUI.SetActive(true);
        }
        }
        else
        {
            lookObject=null;
        }

但文字永远不会消失。我该如何解决?

改为使用 3D 碰撞器触发器

它比每帧制作 ray-cast 效率更高。

// This should be attached to your door
// with a trigger-collider
public class DoorDetector : MonoBehaviour {

    // Player needs a collider and any physics-body too.

    private void OnTriggerEnter(Collider other) {
        if (other.CompareTag("playerTag")){
            // Show the text, or something
        }
    }

    private void OnTriggerExit(Collider other) {
        if (other.CompareTag("playerTag")){
            // Hide the text, or something
        }
    }
}

每当您需要对检测做一些事情时,这是推荐的方法,因为制作 ray-casts per-frame 可能会很昂贵。


如果您想解决您的问题,我的猜测是您忘记禁用 UI 一旦您的 Ray-cast 无法触及(或什么也没打到)。

[SerializeField] 
private float maxDistance = 2f;

void Update()
{
    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;
        if (hit.collider.gameObject.tag == "Door") {
            textUI.SetActive(true);
            centerUI.SetActive(false);
        } else {
            textUI.SetActive(false);
            centerUI.SetActive(true);
        }
    } else {
        lookObject=null;
        // You probably forgot to decative the UI here, once the raycast was out-of-range
        textUI.SetActive(false);
        centerUI.SetActive(false);
    }
    // ...