gpt4 book ai didi

c# - 团结 : Manage AudioManager on all scenes

转载 作者:行者123 更新时间:2023-12-02 03:03:58 27 4
gpt4 key购买 nike

我使用以下代码创建了一个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)的场景中启动它,它就可以很好地工作。但是,出于某些调试目的,我确实单独启动了一些场景,并且未定义包含 AudioManagergameObject 。我应该如何解决这个问题?

最佳答案

所以有两个任务:

  • 您需要AudioManager或者实际上更好地说 AudioSource实例可访问/实例化到任何场景
  • 您想要填充 List<Audio clip>

为了将两者结合在一起,我将使用 ScriptableObject

[CreateAssetMenu]
public class AudioData : ScriptableObject
{
public List<Sound> sounds = new List<Sound>();
}

通过在资源中右键单击创建实例 → 创建AudioData

在这里您可以填充 Sounds 的列表.

然后我会直接使用带有惰性实例化的单例,以便在场景中找不到任何单例时甚至可以与 [RuntimeInitializeOnLoadMethod] 结合使用来初始化一个单例。

Methods marked [RuntimeInitializeOnLoadMethod] are invoked after the game has been loaded.

这毕竟叫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();
}
}

关于c# - 团结 : Manage AudioManager on all scenes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59459321/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com