0

当玩家与 NPC 对撞机发生碰撞并且玩家未与 NPC 发生碰撞时,该消息被禁用时,我试图显示一条消息“按 E 与 NPC 交谈”。该消息确实会在碰撞时出现,但在没有碰撞时它不会被禁用我尝试了很多东西但似乎没有任何效果。任何人都可以帮忙吗?这是我的代码和我尝试过的一些事情:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Task_7 : MonoBehaviour
{
   public GameObject PressEmsg;
   //public bool isNearNPC = true;
  // Start is called before the first frame update
  void Start()
 {
    PressEmsg.gameObject.SetActive(false);
}

// Update is called once per frame
void Update()
{
    Collider[] nearbyColliders = Physics.OverlapSphere(transform.position, 5f);

    //bool isNearNPC = false;
    //we are looping in the array hitColliders
    foreach(Collider collider in nearbyColliders)
    {
        if(collider.gameObject.tag == "NPC")
        {
            PressEmsg.gameObject.SetActive(true);
            print("NPC DETECTED");
            //isNearNPC = true;
        }

        else
        {
            PressEmsg.gameObject.SetActive(false);
            print("NPC NOT DETECTED");
        }
        /*
        else if(collider.gameObject.tag != "NPC")
        {
            PressEmsg.gameObject.SetActive(false);
            print("NPC NOT DETECTED");
        }
        */
        
    }   

    /*foreach(Collider collider1 in notnearbyColliders)
    {
        if(collider1.gameObject.tag != "NPC")
        {
            PressEmsg.gameObject.SetActive(false);
            print("NPC NOT DETECTED");
        }
    }
    */
   
    
}


}
4

2 回答 2

0

如果您根本没有冲突,那么您的循环将不会有任何迭代。所以 deactivate 不会发生,除非你附近有一个没有标签的对象NPC

此外,您将遍历所有附近的对象,并检查它们中的每一个是否具有标签NPC。所以循环完全取决于对撞机迭代的顺序。例如,您可能会发生第一次有标签的点击,然后您有第二次没有标签的点击=>您再次错误地停用了该对象。

您应该更喜欢使用LinqAny,例如

using System.Linq;

...

void Update()
{
    var nearbyColliders = Physics.OverlapSphere(transform.position, 5f);

    // This will be true if any of the nearbyColliders has the tag "NPC"
    // If there are no colliders this will automatically be false accordingly
    var detected = nearbyColliders.Any(collider => collider.CompareTag("NPC"));
    // Basically this equals somewhat doing 
    //var detected = false;
    //foreach(var collider in nearbyColliders)
    //{
    //    if(collider.CompareTag("NPC"))
    //    {
    //        detected = true;
    //        break;
    //    }
    //}

    PressEmsg.gameObject.SetActive(detected);
    print(detected ? "NPC detected" : "NPC not detected");
}

一般来说,出于性能原因,请避免登录Update!即使您的用户看不到日志,它仍然可以完成并且非常昂贵。


注意:在智能手机上输入,但我希望这个想法很清楚

于 2021-01-15T10:17:12.277 回答
0

似乎如果你没有任何碰撞,你就不会进入你的for循环。

在遍历找到的对撞机之前,我会默认消息是不活动的,但我会使用一个变量,所以我实际上只调用了一次消息状态方法:

bool isNearNpc = false;

Collider[] nearbyColliders = Physics.OverlapSphere(transform.position, 5f);

foreach(Collider collider in nearbyColliders)
{
    if(collider.gameObject.tag == "NPC")
    {
        print("NPC DETECTED");
        isNearNpc = true;
    }
}


PressEmsg.gameObject.SetActive(isMessageActive);
print($"NPC DETECTED: { isNearNpc }");
于 2021-01-14T23:26:00.633 回答