C# 为什么Unity看不见,那个玩家是残疾的?

C# 为什么Unity看不见,那个玩家是残疾的?,c#,unity3d,C#,Unity3d,在我在Unity3d上的游戏中,我有一个带有主要摄像头组件的玩家对象。我需要禁用播放器,然后使用另一个摄像头启用另一个对象,但我有sctripts,它可以检测播放器是否使用光线投射查看某个对象。如果带摄像头的播放器被禁用,我就出错了。这就是为什么我会检查播放器是否启用。但出于某种原因,unity忽略了这张支票 void Update () { if (player == null) player = GameObject.FindGameOb

在我在Unity3d上的游戏中,我有一个带有主要摄像头组件的玩家对象。我需要禁用播放器,然后使用另一个摄像头启用另一个对象,但我有sctripts,它可以检测播放器是否使用光线投射查看某个对象。如果带摄像头的播放器被禁用,我就出错了。这就是为什么我会检查播放器是否启用。但出于某种原因,unity忽略了这张支票

   void Update ()
    {
        if (player == null)
            player = GameObject.FindGameObjectWithTag("Player");

        if (Input.GetButton("Fire1"))
            if (DoPlayerLookAtButton() && isAimationReadyToPlay)
                OpenCloseDoor();
    }

    bool DoPlayerLookAtButton()
    {
        if (player != null)
        {
            if (player.activeSelf) // why Unity don't see this string?
            {
                int layerMask = 1 << 9;
                layerMask = ~layerMask;

                RaycastHit _hit;
                // I have error here:
                Ray _ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2, 0));
                bool isHit = Physics.Raycast(_ray, out _hit, 2.0f, layerMask);

                if (isHit && _hit.collider == thisCollider) return true;
                else return false;
            }
            else return false;
        }
        else return false;
    }
编辑1

这里要了解的最重要的一点是GameObject.FindGameObjectWithTag、GameObject.Find和GameObjects的其他FindXXX函数无法也将无法找到场景中不活动的游戏对象

这就是你得到这个错误的原因。在大多数情况下,您有两种选择:

1.从编辑器中分配玩家:

将播放器变量设置为公共变量,然后从编辑器中将播放器分配到播放器插槽

公共游戏对象玩家

这样,您就不需要再次使用GameObject.FindGameObjectWithTag,并且播放器不能为null,除非您显式将其设置为null

2.如果游戏对象在默认情况下必须处于活动状态,则从编辑器中将其激活

使用GameObject.FindGameObjectWithTag在“开始”或“唤醒”功能中的场景开头找到它,然后使用快速设置使其处于活动状态 player.SetActivefalse

最后,Unity默认情况下不支持在活动游戏对象中查找,但下面是可以用来查找它们的函数。不要因为它们速度慢而滥用它们:

按名称在活动游戏对象中查找:

按标记在活动游戏对象中查找:

按层在活动游戏对象中查找:

编辑:

根据您的详细信息,问题出在这里Camera.main.ScreenPointRoay:

如果您的相机处于活动状态,或者您的相机位于处于活动状态的游戏对象下,camera.main将返回null。它将无法找到相机。当它返回null并且您尝试调用它的screenpointoray函数时,您会得到一个异常


此外,如果切换到的场景中有另一个摄影机,则必须确保将该摄影机的标记更改为Main camera(如果该摄影机是用于光线投射的摄影机)。更多信息,请查看帖子。您这样做是因为Camera.main将查找带有MainCamera标记的已启用摄像头。

谢谢!我明白,Unity找不到不活动的对象。我不明白,为什么它看不到player.activeSelf的状态?因为player对象被禁用,Unity无论如何都会在这个条件下执行代码,但是它不应该从您发布的屏幕截图中删除,所以您得到的是NullReferenceException。是不是在代码播放器的那一行。activeSelf?糟糕透了。这就是双击错误时Camera.main.ScreenPointRoay所在的位置?此外,错误是否与您的问题有关。我想我可能写了一些完全不同的东西……我现在明白了。在修改答案之前,我想确定问题出在哪里。请双击Unity Editor中的错误,它会将您带到代码中的错误位置。在评论部分张贴这行代码,不客气。如果没有这个截图,我们会认为问题出在player.activeSelf。快乐编码!
GameObject FindObjectInActiveByName(string name)
{
    Transform[] objs = Resources.FindObjectsOfTypeAll<Transform>() as Transform[];
    for (int i = 0; i < objs.Length; i++)
    {
        if (objs[i].hideFlags == HideFlags.None)
        {
            if (objs[i].name == name)
            {
                return objs[i].gameObject;
            }
        }
    }
    return null;
}
GameObject FindObjectInActiveByTag(string tag)
{

    Transform[] objs = Resources.FindObjectsOfTypeAll<Transform>() as Transform[];
    for (int i = 0; i < objs.Length; i++)
    {
        if (objs[i].hideFlags == HideFlags.None)
        {
            if (objs[i].CompareTag(tag))
            {
                return objs[i].gameObject;
            }
        }
    }
    return null;
}
GameObject FindObjectInActiveByLayer(int layer)
{

    Transform[] objs = Resources.FindObjectsOfTypeAll<Transform>() as Transform[];
    for (int i = 0; i < objs.Length; i++)
    {
        if (objs[i].hideFlags == HideFlags.None)
        {
            if (objs[i].gameObject.layer == layer)
            {
                return objs[i].gameObject;
            }
        }
    }
    return null;
}