微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Unity - AudioClip 数组问题

如何解决Unity - AudioClip 数组问题

我正在尝试在 Unity 中制作音频播放器。 我首先创建了一个 ResourceManager,它有一个 AudioClip[] 数组。

public class ResourceManager : MonoBehavIoUr
{
    public AudioSource audioSrc;
    public AudioClip[] clips;
    private int trackNum = 0;
    
    public void Awake()
    {
        audioSrc = GetComponent<AudioSource>();
        audioSrc.Stop();

    ...omitted...
        
    public void LoadClip()
    {
        audioSrc.clip = clips[trackNum];

    }
}

以便它们出现在 Clips 拖放框中。

enter image description here

但是,我想让 ResourceManager 中的 AudioClip 数组是静态的,以便其他脚本(例如 PlayPause.cs 可以静态访问 clips(通过函数调用)。 但问题是一旦我将 clips 设为静态,拖放操作就会消失。

有办法解决吗?或者有更好的设计模式吗?谢谢。

解决方法

你可以例如简单地做

public class ResourceManager : MonoBehaviour
{
    ...

    // This is the one in the Inspector
    // Usually I keep the Inspector private and only provide public access 
    // where needed via properties 
    [SerializeField] private AudioClip[] clips;

    // This will be set in Awake to the ones from the Inspector
    // readonly for others,only this class can assign it
    public static AudioClip[] Clips { get; private set; }
    
    public void Awake()
    {
        Clips = clips;

        ...
    }
}

建议的替代方法是使 ResourceManager 成为所谓的 singleton,例如

public class ResourceManager : MonoBehaviour
{
    // Here you store your own instance reference  
    // and provide public readonly access
    public static ResourceManager Instance { get; private set; }

    [SerializeField] private AudioClip[] clips;

    public AudioClip[] Clips => clips;

    ...
    
    public void Awake()
    {
        // Make sure only one instance exists at a time
        if(Instance && Instance != this)
        {
            Destroy(gameObject);
            return;
        }

        _instance = this;

        // optional: Don't destroy this instance when the scene is switched
        // Careful: Make sure this applies also to the AudioSource instance!
        // For now I assume it is either attached to this object or a child
        // if not simply do the same DontDestroyOnLoad on it as well
        DontDestroyOnLoad (this.gameObject);         

        ...
    }
        
    public void LoadClip()
    {
        audioSrc.clip = clips[trackNum];
    }
}

然后到处访问ReaourcesManager.Instance.Clips


或者 singleton 的内置替代方案是使用 FindObjectOfType,因此场景中的任何其他脚本实际上都可以简单地访问

FindObjectOfType<ResourcesManager>().clips

无需您进行任何更改;)

除非我说我会做到

[SerializeField] private AudioClip[] clips;

public IReadonlyList<AudioClip> Clips => clips;

当然取决于你想对剪辑做什么,但这样数组就不能被任何其他脚本改变

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。