我使用以下代码创建了一个c0, c1 = map(pd.Series, zip(*[(a, b)
for s, c in df.groupby('sport')['Country(s)']
for a, b in product(c, c)]))
pd.crosstab(c0, c1).rename_axis(None).rename_axis(None, axis=1)
Australia Brazil South_Africa Uk
Australia 3 0 1 3
Brazil 0 2 1 2
South_Africa 1 1 2 2
Uk 3 2 2 5
:
AudioManager
只要我在定义using System;
using UnityEngine.Audio;
using UnityEngine;
public class AudioManager : MonoBehaviour
{
public Sound[] sounds;
public static AudioManager instance;
void Awake()
{
if (instance == null)
{
instance = this;
}
else
{
Destroy(gameObject);
return;
}
DontDestroyOnLoad(gameObject);
}
public void Play(SoundType soundType)
{
Sound s = Array.Find(this.sounds, sound => sound.soundType == soundType);
s.source = gameObject.AddComponent<AudioSource>();
s.source.clip = s.clip;
// We define volume and pitch here to be able to change them in real time
s.source.volume = s.volume;
s.source.pitch = s.pitch;
s.source.Play();
}
}
(包含此gameObject
)的场景中启动它,它的效果就很好。
但是,出于某些调试目的,我确实单独启动了某些场景,并且未定义包含MonoBehaviour
的{{1}}。我应该如何解决这个问题?
答案 0 :(得分:2)
您可以使用自动构造的单例。第一次调用AudioManager.Instance
时,它将生成一个新的游戏对象并将AudioManager
脚本附加到该对象。
public class AudioManager : MonoBehaviour
{
static AudioManager instance;
public static AudioManager Instance => instance ?? (instance = new GameObject("AudioManager", typeof(AudioManager)).GetComponent<AudioManager>());
public void PlaySound(SoundType soundType)
{
Debug.Log("Play Sound: " + soundType);
}
}
答案 1 :(得分:2)
所以有两个任务:
AudioManager
或更准确地说是AudioSource
实例,以便可以在任何场景中访问/实例化List<Audio clip>
为了使两者融合在一起,我将使用ScriptableObject
[CreateAssetMenu]
public class AudioData : ScriptableObject
{
public List<Sound> sounds = new List<Sound>();
}
通过右键单击资产→创建→ AudioData
创建实例您可以在此处填充Sounds
的列表。
然后,我将直接使用您的Singleton进行惰性实例化,以便在场景中找不到甚至与[RuntimeInitializeOnLoadMethod]
组合的情况下初始化一个实例。
标记为
[RuntimeInitializeOnLoadMethod]
的方法在游戏加载后被调用。
在完成所有Awake
调用之后将调用此方法,因此该实例要么存在,要么立即创建。
例如
public class AudioManager : MonoBehaviour
{
// if you have it in the scene you can reference these right away
[SerializeField] private AudioData audioData;
[SerializeField] private AudioSource audioSource;
// backing field for actually store the Singleton instance
private static AudioManager _instance;
// public access for the Singleton
// and lazy instantiation if not exists
public static AudioManager Instance
{
get
{
// if exists directly return
if(_instance) return instance;
// otherwise search it in the scene
_instance = FindObjectOfType<AudioManager>();
// found it?
if(_instance) return instance;
// otherwise create and initialize it
CreateInstance();
return _instance;
}
}
private void Awake()
{
if (_instance && _instance != this)
{
Destroy(gameObject);
return;
}
InitializeInstance(this);
}
[RuntimeInitializeOnLoadMethod]
private static void CreateInstance()
{
// skip if already exists
if(_instance) return;
InitializeInstance(new GameObject (nameof(AudioManager)).AddComponent<AudioManager>());
}
private static void InitializeInstance(AudioManager instance)
{
_instance = instance;
DontDestroyOnLoad(gameObject);
if(!_instance.audioSource) _instance.audioSource = _instance.AddComponent<AudioSource>();
if(_instance.audioData) return;
var audioDatas = Resources.FindObjectsOfType<AudioData>();
if(audioDatas.Length == 0)
{
Debug.LogError("No Instance of AudioData found! Don't forget to create that ScriptableObject!");
return;
}
_instance.audioData = audioDatas[0];
}
public void Play(SoundType soundType)
{
Sound s = audioData.sounds.First(sound => sound.soundType == soundType);
s.source = audioSource;
s.source.clip = s.clip;
// We define volume and pitch here to be able to change them in real time
s.source.volume = s.volume;
s.source.pitch = s.pitch;
s.source.Play();
}
}
答案 2 :(得分:0)
使AudioManager单身,并在需要它的每个场景中访问它。
使用以下模式:http://wiki.unity3d.com/index.php/Singleton
请注意,您不想要执行
s.source = gameObject.AddComponent<AudioSource>();
每次玩。在播放声音时,您将获得一堆AudioSources。您应该检查是否存在,然后根据需要创建它。另外,如果一次只播放一种声音,则只能使用一个音频源。