【问题标题】:How to make void update let audio play until end?如何使无效更新让音频播放直到结束?
【发布时间】:2019-09-09 07:55:39
【问题描述】:

我在这件事上大发雷霆。

如何使这段代码使分配的音频文件完全运行?我知道更新方法只运行每一帧,但我如何让它运行直到音频完成?音频开始然后立即中断,因为它是每一帧。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class checkifdone : MonoBehaviour
{

public AudioSource checkwin;
private bulbmanager bulbreq;
// Start is called before the first frame update
void Start()
{
    bulbreq = FindObjectOfType<bulbmanager>();
}

// Update is called once per frame
void Update()
{
    checkaudio();
}

void checkaudio()
{
    if (bulbreq.bulbcount >= 8)
    {
        checkwin.Play();
    }
}

}

我尝试将它放在 void start() 中,但这根本没有帮助,因为 start 是关卡的开始。

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    我想通了。基本上,这个脚本在一个空对象上,必须检查bulbcount是否为8,我将检查移到另一个游戏对象并将音频播放功能留在同一个地方。我还将 onEnabled 用于将播放声音的游戏对象,并在一开始使其处于非活动状态。

    因此,当另一个游戏对象(检查灯泡计数所在的位置)知道灯泡计数为 8 时,它将启用音频播放器,并且 (OnEnabled) 它将播放声音。

    这是另一个游戏对象(检查灯泡计数的对象)上的脚本:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine.SceneManagement;
    using UnityEngine;
    
    public class LampScript : MonoBehaviour
    {
    
        private bulbmanager bulbreq;
        public GameObject wincheck;
        //private bulbsmustcollect bulblvl;
        // Start is called before the first frame update
        void Start()
        {
            bulbreq = FindObjectOfType<bulbmanager>();
    
            //bulblvl = FindObjectOfType<bulbsmustcollect>();
        }
    
        // Update is called once per frame
        void Update()
        {
            if (bulbreq.bulbcount >= 8)
            {
                wincheck.gameObject.SetActive(true);            
    
            }
        }
    
        private void OnTriggerEnter2D(Collider2D other)
        {
            if (other.tag == "Player")
            {
                if (bulbreq.bulbcount >= 8)
                {
                    //loop.Stop();
                    SceneManager.LoadScene("Level 2");
                }
    
            }
        }
    }
    

    这是我在音频播放器中输入的代码:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class checkifdone : MonoBehaviour
    {
    
        public AudioSource checkwin;
        public GameObject wincheck;
        // Start is called before the first frame update
        void Start()
        {
            wincheck.gameObject.SetActive(false); //This is the same object where script is.
    
    
        }
    
        private void OnEnable()
        {
            checkwin.Play();
    
        }
    }
    

    当然,我们不要忘记分配所需的一切。音频现在播放到完整,因为它独立于其他脚本文件的更新功能。不确定这是否是最好的方法,但它有效!

    【讨论】:

      【解决方案2】:

      来自AudioSource.Play

      如果 AudioSource.clip 设置为正在播放的同一剪辑,则剪辑听起来像是重新开始。 AudioSource 将假定任何 Play 调用都会有一个新的音频剪辑要播放。

      因此,如果您每帧调用Play,它总是从每帧的开头开始。


      您可以简单地添加一个 bool 标志来检查它是否已经播放,而不是为此添加多个组件和对象。或者更简单:简单地禁用组件,这样Update 就不再被调用了

      public class checkifdone : MonoBehaviour
      {
          public AudioSource checkwin;
      
          private bulbmanager bulbreq;
      
          // Flag to control of sound was already played
          private bool alreadyPlayed;
      
          private void Start()
          {
              bulbreq = FindObjectOfType<bulbmanager>();
          }
      
          private void Update()
          {
              // If was already played do nothing
              if(alreadyPlayed) return;
      
              checkaudio();
          }
      
          private void checkaudio()
          {
              if (bulbreq.bulbcount < 8) return;
      
              // Set flag so Update is skipped in the future
              alreadyPlayed = true;
      
              // Or alternatively simply
              // disable this component:
              enabled = false;
      
              checkwin.Play();
          }
      }
      

      【讨论】:

        【解决方案3】:

        如果您使用 Unity 3d 和 C#,请尝试使用此功能。 它将在您的检查器面板中播放链接到 checkwin 的音频文件。

        source.PlayOneShot(checkwin,vol);
        // b is a bool
        // this should stop either .play() or PlayOneShot() repeating or restarting
        if(b){play audio function; b = false;}
        

        【讨论】:

        • 仅此一项无济于事,因为它仍然在每一帧都被调用,因此您将有很多声音并行播放;)
        • 好吧,我假设有人会在 if 语句中使用它来触发它。 :D 它假设播放音频一次不会与 checkwin.play() 连续重叠。
        • 不完全是 ;) checkwin.Play() 启动当前附加的 AudioClip。如果它已经在运行,它会再次从头开始。 checkwin.PlayOneShot(audioClip);(顺便说一句,checkwin 是一个 AudioSource,不能作为 PlayOneShot 的参数;))重播一次完整的音频剪辑。如果它被多次调用,则剪辑将并行播放。
        • 是的,这就是为什么我提到使用 if 语句... -> if(b){play music; b = false} 这将完全停止重复播放或重新启动的任何一种方式。 :P
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-15
        • 1970-01-01
        • 1970-01-01
        • 2021-10-29
        • 1970-01-01
        相关资源
        最近更新 更多