访问非静态成员需要对象引用
本文关键字:对象引用 静态成员 访问 | 更新日期: 2023-09-27 18:03:35
我有这个错误出现,我不知道为什么…我试着查了一下,人们说创建一个类的对象或创建静态方法…但我不确定如何。
下面是我的代码:
public class SoundManager : MonoBehaviour {
public List<AudioSource> audioSounds = new List<AudioSource>();
public double minTime = 0.5;
public static void playSound(AudioClip sourceSound, Vector3 objectPosition, int volume, float audioPitch, int dopplerLevel)
{
bool playsound = false;
foreach (AudioSource sound in audioSounds) // Loop through List with foreach
{
if (sourceSound.name != sound.name && sound.time <= minTime)
{
playsound = true;
}
}
if(playsound) {
AudioSource.PlayClipAtPoint(sourceSound, objectPosition);
}
}
}
你应该设置audioSounds和minTime成员为static:
public static List<AudioSource> audioSounds = new List<AudioSource>();
public static double minTime = 0.5;
但是我会考虑使用单例对象而不是静态成员:
public class SoundManager : MonoBehaviour
{
public List<AudioSource> audioSounds = new List<AudioSource>();
public double minTime = 0.5;
public static SoundManager Instance { get; private set; }
void Awake()
{
Instance = this;
}
public void playSound(AudioClip sourceSound, Vector3 objectPosition, int volume, float audioPitch, int dopplerLevel)
{
bool playsound = false;
foreach (AudioSource sound in audioSounds) // Loop through List with foreach
{
if (sourceSound.name != sound.name && sound.time <= minTime)
{
playsound = true;
}
}
if(playsound) {
AudioSource.PlayClipAtPoint(sourceSound, objectPosition);
}
}
}
2020年9月更新:
六年后,它仍然是我在StackOverflow上最受欢迎的答案之一,所以我觉得有义务补充:单例是一种模式,它在未来会产生很多问题,我个人认为它是一种反模式。它可以从任何地方访问,并且在不同的游戏系统中使用singleton会在项目的不同部分之间创建无形的依赖关系。
如果你刚刚学习编程,现在使用单例是可以的。但是,请考虑阅读依赖注入、控制反转和其他架构模式。至少把它归类为"我以后要学的东西"。当您第一次了解它们时,这可能听起来有点小题大做,但是适当的体系结构可以成为中型和大型项目的救星。
我猜你在访问audioSounds
和minTime
时遇到了错误,对吧?
问题是你不能从static methods
访问instance members
。这意味着,静态方法是一种只存在一次的方法,可以被所有其他对象使用(如果它的访问修饰符允许的话)。
实例成员是为对象的每个实例创建的。因此,如果您创建了十个实例,运行时如何知道在所有这些实例中,应该访问哪个audioSounds
列表?
就像其他人说的,让你的audioSounds
和minTime
是静态的,或者你可以让你的方法是一个实例方法,如果你的设计允许的话。
playSound是一个静态方法,意味着它在程序加载时存在。audioSounds和minTime是SoundManager实例变量,这意味着它们将存在于SoundManager的一个实例中。你没有创建一个SoundManager的实例,所以audioSounds不存在(或者它存在,但你没有一个SoundManager对象的引用来查看)。
要解决这个问题,你可以将audioSounds设置为静态:
public static List<AudioSource> audioSounds = new List<AudioSource>();
public static double minTime = 0.5;
,所以它们将被创建,并可能以与PlaySound相同的方式被引用。或者你可以在你的方法中创建一个SoundManager的实例:
SoundManager soundManager = new SoundManager();
foreach (AudioSource sound in soundManager.audioSounds) // Loop through List with foreach
{
if (sourceSound.name != sound.name && sound.time <= soundManager.minTime)
{
playsound = true;
}
}
playSound是您的类中的静态方法,但您指的是audioSounds
或minTime
等成员,未声明为static
,因此它们需要SoundManager sm = new SoundManager();
分别作为sm.audioSounds
或sm.minTime
操作
解决方案:
public static List<AudioSource> audioSounds = new List<AudioSource>();
public static double minTime = 0.5;
使您的audioSounds
和minTime
变量作为静态变量,因为您在静态方法(playSound
)中使用它们。
将方法标记为static
可以防止在该方法中使用非静态(实例)成员。
要了解更多,请阅读SO QA:
c#中的Static关键字