public class AudioUIManager : MonoBehavIoUr //Only one of these in the scene { public AudioClip genericUISound; //This is set in the inspector. }
public class AudioUITextAnimation : MonoBehavIoUr { [SerializeField] private AudioClip specifiedUISound; //This is not set in the inspector [SerializeField] private AudioUIManager audioUIManager; // I get a reference to this elsewhere void Start() { //Use generic sounds from audio manager if nothing is specified. specifiedUISound = specifiedUISound ?? audioUIManager.genericUISound; print(specifiedUISound); } }
我在这里想要实现的是让指定的UISound字段使用在检查器中分配给它的声音.如果未分配声音,则使用UI管理器中的通用声音.这样可以节省我为需要相同声音的数百万个按钮分配相同的声音,但如果我愿意,可以选择为一个按钮设置特定的声音.
但是,null-coalessing运算符将null指定为namedUISound,即使它为null且audioUIManager的声音不为null.另外,如果我使用三元运算符来检查null,我可以使用它:
specifiedUISound = specifiedUIsound == null ? audioUIManager.genericUISound : specifiedUISound;
我是否误解了空合并运算符?为什么会这样?
编辑:Jerry Switalski指出,这只发生在serialUISound被序列化时. (如果它是公共的或者它具有[SerializeField]属性).任何人都可以了解这里发生的事情吗?
解决方法
When a MonoBehavIoUr has fields,in the editor only,we do not set those fields to “real null”,but to a “fake null” object. Our custom == operator is able to check if something is one of these fake null objects,and behaves accordingly. While this is an exotic setup,it allows us to store information in the fake null object that gives you more contextual information when you invoke a method on it,or when you ask the object for a property. Without this trick,you would only get a NullReferenceException,a stack trace,but you would have no idea which GameObject had the MonoBehavIoUr that had the field that was null.
在编辑器中运行时,Unity会使用实际上不为null的sentinel值替换序列化的null.这允许他们在某些情况下提供更多信息性错误消息.
指定的UISound是否等于null?这取决于你的要求. C#有多个“平等”概念,包括data equality and reference equality.
一些检查会说值相等:==和Object.Equals
其他人会说他们不平等:和Object.ReferenceEquals
此行为只会在编辑器中发生.在独立构建中运行时,任何空值都将为null.