我不太确定如何准确地描述它,因此让我向您展示发生了什么。

我有一个PlayerControls脚本,它看起来像这样(注意:我除去了必需品之外的所有内容)。

namespace Player.Controls {
    internal class PlayerControls: MonoBehaviour {
        public bool IsClimbing { get; private set; } = false;
        public bool IsGrounded { get; private set; } = false;
    }
}


这些变量是在此类中设置的,具体取决于玩家是否在攀爬/接触地面。该脚本位于场景中的“玩家” GameObject上。


我还有一个名为PlayerController的脚本,它看起来像这样

using Player.Controls;
public class PlayerController: Singleton<PlayerController> {
    internal PlayerStats stats = new PlayerStats();
    //PlayerStats nested class (see below)
}


Singleton类仅检查泛型类型是否为null,如果是,它将使用FindObjectOfType获取实例。该脚本也位于“播放器” GameObject上。


PlayerController类中,我有一个名为PlayerStats的嵌套类。看起来像这样

internal class PlayerStats : PlayerControls {
    public new bool IsClimbing { get { return base.IsClimbing; } }
    public new bool IsGrounded { get { return base.IsGrounded; } }
}


请注意,此嵌套类是从PlayerControls继承的。



这个想法是,除了PlayerControls以外的所有其他类都无法访问PlayerController类,并且我想要获取的有关播放器的任何信息都可以通过获取播放器的实例(通过单例)并访问PlayerStats来获取。变量。

例如,假设保存实例的Singleton中的变量称为Instance,则可以执行PlayerController.Instance.stats.IsClimbing;一切都按预期进行,除了一件事情。


Awake类的PlayerController方法中,我这样做

private void Awake() {
    Debug.LogFormat("In PlayerController Awake(). Is PlayerController.stats null? {0}",
    (stats.Equals(null) ? "Yes" : "No"));

    Debug.LogFormat("IsClimbing : {0}", stats.IsClimbing);
}


在输出窗口中,它打印
In PlayerController Awake(). Is PlayerController.stats null? Yes
IsClimbing : False

如果我还在IsClimbing方法中放置了相同的Update()调试,则该值对于我开始攀爬时是正确的。


所以,最后,我的问题是,如果PlayerStatsstats,如何使用stats变量访问null类的变量?我以为可能是直接调用了PlayerControls属性,所以我更改了它们的名称,删除了new内的PlayerStats甚至将调试语句放在了PlayerStats内的一个属性中,肯定会被调用。例如,public bool IsClimbing { get { Debug.Log("Called IsClimbing inside PlayerStats."); return base.Climbing; } }

如果它被调用并正常工作,怎么可能是null?我问我的教授,他似乎也不知道为什么。这到底是怎么回事?


编辑:

根据要求,Singleton类:

public abstract class Singleton<T>: MonoBehaviour where T : MonoBehaviour {
    private static T instance;

    public static T Instance {
        get {
            if(instance == null) {
                instance = FindObjectOfType<T>();
            }
            return instance;
        }
    }
}


Here is an image of the console output.

最佳答案

在Unity论坛it appears that the Equals method has been overridden上(在Object最终源自的MonoBehaviour上)进行挖掘,这就是为什么将MonoBehaviournull进行比较无法提供预期的结果。我链接的答案建议这样的代码更合适:

stats == null || stats.Equals(null)

07-24 09:30