C# 使用PlayOneShot后一切都会中断
在我正在做的一个游戏中,玩家使用立方体开门。当玩家在门附近与立方体互动时,门会滑开。我现在正试着让它在滑开时发出门应该发出的声音,但我遇到了一些问题。当我试图为门添加声音时,它忽略了门应该完全打开的部分 以下是我所做的: 我在多维数据集的子对象CORE中添加了一个音频源,因为多维数据集对象已经包含了一个音频源,该音频源将与此声音同时播放,并在多维数据集的脚本中分配给它C# 使用PlayOneShot后一切都会中断,c#,unity3d,C#,Unity3d,在我正在做的一个游戏中,玩家使用立方体开门。当玩家在门附近与立方体互动时,门会滑开。我现在正试着让它在滑开时发出门应该发出的声音,但我遇到了一些问题。当我试图为门添加声音时,它忽略了门应该完全打开的部分 以下是我所做的: 我在多维数据集的子对象CORE中添加了一个音频源,因为多维数据集对象已经包含了一个音频源,该音频源将与此声音同时播放,并在多维数据集的脚本中分配给它 公共音频源Woosh void Start() { //Debug.Log("Script initialized!"
公共音频源Woosh代码>
void Start()
{
//Debug.Log("Script initialized!");
Hm = gameObject.GetComponent<AudioSource>();
anim = GameObject.Find("TheFirstDoor").GetComponent<Animator>();
//Door = GameObject.Find("TheFirstDoor").GetComponent<AudioSource>();
Woosh = GameObject.Find("CORE").GetComponent<AudioSource>();
}
现在是脚本的IEnumerator部分,PlayDaWoosh()
我知道最后一段代码有点凌乱,但这是我能想到的最好的东西
这是完整的脚本,以防你好奇
using System.Collections;
使用System.Collections.Generic;
使用UnityEngine
公共类多维数据集核心:单行为
{
公共音频源Hm;//Hm!!!
二等兵布尔扮演=假;
公共浮点播放超时=0.0f;
公共静态bool CanBeKey=false;
公共动画;
public static bool HasPlayedFirstTime=false;
公共静态声源门;
公共音频源Woosh
// Start is called before the first frame update
void Start()
{
//Debug.Log("Script initialized!");
Hm = gameObject.GetComponent<AudioSource>();
anim = GameObject.Find("TheFirstDoor").GetComponent<Animator>();
//Door = GameObject.Find("TheFirstDoor").GetComponent<AudioSource>();
Woosh = GameObject.Find("CORE").GetComponent<AudioSource>();
}
// Update is called once per frame
void Update()
{
if(HasPlayed == true)
{
if (PlayTimeOut < 0.0f)
{
HasPlayed = false;
}
PlayTimeOut -= Time.smoothDeltaTime;
}
}
public void OnActivate()
{
if(HasPlayed == false) //Have I played? Has the Time out passed?
{
HasPlayedFirstTime = true;
Hm.Play();
HasPlayed = true;
PlayTimeOut = 30.0f;
if(CanBeKey == true)
{
anim.Play("Door_Open");
//Door.Play();
StartCoroutine(PlayDaWoosh());
Debug.Log("OPENING!");
}
}
}
private void OnTriggerEnter(Collider other)
{
if(other.gameObject.name == "SecondDoor")
{
anim = GameObject.Find("DoorSecond").GetComponent<Animator>();
}
if(other.gameObject.name == "ThirdDoor")
{
anim = GameObject.Find("TheThirdDoor").GetComponent<Animator>();
}
if(other.gameObject.name == "FourthDoor")
{
anim = GameObject.Find("TheFourthDoor").GetComponent<Animator>();
}
}
IEnumerator PlayDaWoosh()
{
Woosh.PlayOneShot(Woosh.clip);
yield return new WaitForSeconds(Woosh.clip.length);
}
//在第一次帧更新之前调用Start
void Start()
{
//Log(“脚本已初始化!”);
Hm=gameObject.GetComponent();
anim=GameObject.Find(“第一扇门”).GetComponent();
//Door=GameObject.Find(“第一扇门”).GetComponent();
Woosh=GameObject.Find(“核心”).GetComponent();
}
//每帧调用一次更新
无效更新()
{
if(HasPlayed==true)
{
如果(播放超时<0.0f)
{
HasPlayed=false;
}
PlayTimeOut-=Time.smoothDeltaTime;
}
}
激活时的公共无效()
{
if(HasPlayed==false)//我玩了吗?超时了吗?
{
HasPlayedFirstTime=true;
嗯,Play();
hasplay=true;
播放超时=30.0f;
如果(CanBeKey==true)
{
动漫游戏(“开门”);
//门。玩();
开始例行程序(PlayDaWoosh());
Log(“打开!”);
}
}
}
专用空对撞机(对撞机其他)
{
如果(other.gameObject.name==“SecondDoor”)
{
anim=GameObject.Find(“DoorSecond”).GetComponent();
}
如果(other.gameObject.name==“ThirdDoor”)
{
anim=GameObject.Find(“TheThirdDoor”).GetComponent();
}
if(other.gameObject.name==“第四扇门”)
{
anim=GameObject.Find(“第四扇门”).GetComponent();
}
}
IEnumerator PlayDaWoosh()
{
播放镜头(Woosh.clip);
产生返回新WaitForSeconds(Woosh.clip.length);
}
}
预期结果:开门和声音播放
实际结果:除非我删除与Woosh
IEnumerator PlayDaWoosh()
{
Woosh.PlayOneShot(Woosh.clip);
yield return new WaitForSeconds(Woosh.clip.length);
}
如果我不够具体,或者问题在其他地方得到了回答,我会提前道歉。我在这里相对较新。看起来这与协同程序处理框架的方式有关。试着阅读这篇文章,看看它是否有助于你解决问题:在哪里调用了OnActivate()方法?@Wolfik OnActivate()当玩家与多维数据集进行交互时,当玩家走向多维数据集时,会弹出一条文本,指示玩家按“E”进行交互。多维数据集有一个组件,当玩家进入框碰撞器并按下按钮时,该组件将调用脚本的该部分。@RossGurbutt感谢您提供的链接,我了解了很多关于协同程序的知识,并发现了StopCoroutine()
函数。如果可以的话,我会把你的回答标记为答案,因为你使我能够解决这个问题。在start例程(PlayDaWooosh())下代码>我插入了一个StopCoroutine(PlayDaWoosh())
然后在枚举器本身中,我删除了yield return new并放置了一个yield return null
,以指示协同程序停止它正在做的事情。再次感谢您的帮助,门现在可以正常工作了。
// Start is called before the first frame update
void Start()
{
//Debug.Log("Script initialized!");
Hm = gameObject.GetComponent<AudioSource>();
anim = GameObject.Find("TheFirstDoor").GetComponent<Animator>();
//Door = GameObject.Find("TheFirstDoor").GetComponent<AudioSource>();
Woosh = GameObject.Find("CORE").GetComponent<AudioSource>();
}
// Update is called once per frame
void Update()
{
if(HasPlayed == true)
{
if (PlayTimeOut < 0.0f)
{
HasPlayed = false;
}
PlayTimeOut -= Time.smoothDeltaTime;
}
}
public void OnActivate()
{
if(HasPlayed == false) //Have I played? Has the Time out passed?
{
HasPlayedFirstTime = true;
Hm.Play();
HasPlayed = true;
PlayTimeOut = 30.0f;
if(CanBeKey == true)
{
anim.Play("Door_Open");
//Door.Play();
StartCoroutine(PlayDaWoosh());
Debug.Log("OPENING!");
}
}
}
private void OnTriggerEnter(Collider other)
{
if(other.gameObject.name == "SecondDoor")
{
anim = GameObject.Find("DoorSecond").GetComponent<Animator>();
}
if(other.gameObject.name == "ThirdDoor")
{
anim = GameObject.Find("TheThirdDoor").GetComponent<Animator>();
}
if(other.gameObject.name == "FourthDoor")
{
anim = GameObject.Find("TheFourthDoor").GetComponent<Animator>();
}
}
IEnumerator PlayDaWoosh()
{
Woosh.PlayOneShot(Woosh.clip);
yield return new WaitForSeconds(Woosh.clip.length);
}