繁体   English   中英

在Unity C#中使用脚本播放声音时未将对象引用设置为对象的实例

[英]Object Reference not set to an instance of an object while play sound using script in unity c#

我想使用脚本播放和暂停游戏中的声音。 我有一个声音管理器脚本来加载和播放声音文件。 我尝试播放其他脚本的音频。 但是,在我编写了用于播放音频的代码的其他脚本上 ,显示错误消息“ 对象引用未设置为对象的实例 ”。

声音管理器脚本

using UnityEngine;
using System.Collections;

public class soundManager : MonoBehaviour {

    public static AudioSource au_GameStart;
    public static AudioSource au_afterStart;
    public static AudioSource au_carStart;
    public static AudioSource au_go;
    public static AudioSource au_strike;

    public static bool muteStatus;
    public static soundManager instance;
    void Start () {
        muteStatus = false;
        instance=this;
        au_GameStart = (AudioSource)gameObject.AddComponent <AudioSource>();
        au_afterStart = (AudioSource)gameObject.AddComponent <AudioSource>();
        au_carStart = (AudioSource)gameObject.AddComponent <AudioSource>();
        au_go = (AudioSource)gameObject.AddComponent <AudioSource>();
        au_strike = (AudioSource)gameObject.AddComponent <AudioSource>();

        AudioClip clip_GameStart;
        clip_GameStart = (AudioClip)Resources.Load ("SFX/game_start");
        au_GameStart.clip = clip_GameStart;
        au_GameStart.loop = false;

        AudioClip clip_AfterStart;
        clip_AfterStart = (AudioClip)Resources.Load ("SFX/after_start");
        au_afterStart.clip = clip_AfterStart;
        au_afterStart.loop = false;

        AudioClip clip_carStart;
        clip_carStart = (AudioClip)Resources.Load ("SFX/car_start");
        au_carStart.clip = clip_carStart;
        au_carStart.loop = false;

        AudioClip clip_GO;
        clip_GO = (AudioClip)Resources.Load ("SFX/go");
        au_go.clip = clip_GO;
        au_go.loop = false;

        AudioClip clip_Strike;
        clip_Strike = (AudioClip)Resources.Load ("SFX/strike");
        au_strike.clip = clip_Strike;
        au_strike.loop = true;
}

其他脚本

void Start()
{
soundManager.au_GameStart.Play();
}

当我运行unity game时,它在其他脚本中给出了错误提示“对象引用未设置为对象的实例”。 我已经将soundmanager脚本附加到名为SoundManager的游戏对象上。 SoundManager游戏对象会在播放模式下加载声音。

由于Start()otherscript之前执行Start()soundManager soundManager类中的Start()更改为Awake()应该可以解决此问题。

要么

如果您不想重命名,则可以更改脚本执行顺序

更新:正如Everts在其评论中所指出的那样,通常不建议在Start()或Awake中进行初始化,因为除非您明确指定了Script Execution Order,否则无法保证其执行顺序。 但是,即使脚本执行命令也可能导致难以理解的代码,因为脚本执行命令本身在代码中不可见。

因此,我们的想法是,创建一个Init(),以便完全控制该对象的初始化。 如果在Init()旁边需要初始化其他一些对象,请调用其中的Init()。

编辑:当您到达一个类(ClassA)依赖于另一类(ClassB)的地步时,ClassA触发ClassB是必要的。

public class ClassB : MonoBehaviour
{
    [SerializeField] private MonoA monoA = null;
    public void Init(){
        this.monoA = this.gameObject.GetComponent<MonoA>();
    }
    public void GetMonoAValue(){
        if(this.monoA == null){  this.monoA = this.gameObject.GetComponent<MonoA>(); }
        return this.monoA.Value;
    }
}

public class ClassA:MonoBehaviour
{
     private void Start(){
         ClassB classB = FindObjectOfType<ClassB>();
         classB.Init();
         Value v = classB.GetMonoAValue(); 
     }
}

这种情况非常简单,您可以直接调用GetMonoAValue,因为它会在null值的情况下进行初始化。 这是示例,您的Init方法可能包含更多代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM