当Player与具有特定标签的对象碰撞时,Unity3D播放声音

时间:2019-12-11 12:31:14

标签: c# unity3d audio collision

我使用Unity 2019.2.14f1创建一个简单的3D游戏。

在那个游戏中,我想在播放器与带有特定标签的gameObject碰撞时播放声音。

MainCamera有一个音频侦听器,我在ThridPersonController内部使用我的头像的Cinemachine Free Look(我正在使用Standard Assets附带的那个-但我隐藏了Ethan并添加了自己的字符/头像)。

带有我要销毁的标签的游戏​​对象有一个音频源:

Audio Source on the GameObject with the specific tag


为了使声音在碰撞时播放,我首先创建了一个空的gameObject作为AudioManager,然后向其中添加了一个新组件(C#脚本):

using UnityEngine.Audio;
using System;
using UnityEngine;

public class AudioManager : MonoBehaviour
{

    public Sound[] sounds;

    // Start is called before the first frame update
    void Awake()
    {
        foreach (Sound s in sounds)
        {
            s.source = gameObject.AddComponent<AudioSource>();
            s.source.clip = s.clip;

            s.source.volume = s.volume;
            s.source.pitch = s.pitch;
        }
    }

    // Update is called once per frame
    public void Play (string name)
    {
        Sound s = Array.Find(sounds, sound => sound.name == name);
        s.source.Play();
    }
}

并创建了脚本Sound.cs:

using UnityEngine.Audio;
using UnityEngine;

[System.Serializable]
public class Sound
{
    public string name;

    public AudioClip clip;

    [Range(0f, 1f)]
    public float volume;
    [Range(.1f, 3f)]
    public float pitch;

    [HideInInspector]
    public AudioSource source;
}

然后,在Unity UI中,我进入了GameObject AudioManager中的Inspector,并在我命名的脚本中添加了一个新元素:CatchingPresent。

AudioManager - Sound that I want to play when the player collides with an object.

在“第三人称角色”脚本上,为了在与游戏对象碰撞时销毁游戏对象(带有特定标签),我添加了以下内容:

void OnCollisionEnter(Collision other)
        {
            if (other.gameObject.CompareTag("Present"))
            {
                Destroy(other.gameObject);
                count = count - 1;
                SetCountText();

            }
        }

该功能正常,因为特定对象在碰撞时消失了。现在,为了在播放器与带有标签的对象发生冲突时播放声音“ CatchingPresent”,在本例中为Present,我尝试将以下内容添加到{{1 }}:

  • if

但是我得到了错误:

  

找不到类型或名称空间名称“ AudioManager”(您是   缺少using指令或程序集引用?)

  • OnCollisionEnter

但是我得到了错误:

  

名称'AudioManager'在当前上下文中不存在

由于所有编译器错误都需要在进入“播放模式”之前修复,因此,有关如何使播放器与带有标签FindObjectOfType<AudioManager>().Play("CatchingPresent");的游戏对象发生冲突之后播放声音的任何指导,我们将感激不尽。


编辑1:假设它很有帮助,这里将显示完整的ThirdPersonUserControl.cs:

AudioManager.instance.Play("CatchingPresent");

编辑2:Unity中的层次结构:

Hierarchy in Unity

2 个答案:

答案 0 :(得分:0)

通过简单地将音频源添加到ThirdPersonController(具有我要调用的AudioClip),并向if语句添加def FindIdInColumn(column,callBack,fieldName): for i in range(0,len(column)): collectionJson = column[i] if type(collectionJson) !=str or collectionJson == '': continue idIndex = 0 idIndex = collectionJson.find(fieldName,idIndex,len(collectionJson)) while idIndex != -1: idStr = '' j = idIndex+5 while j<len(collectionJson) and collectionJson[j]!=',': if not(collectionJson[j].isspace()) and collectionJson[j].isnumeric(): idStr = idStr + collectionJson[j] j=j+1 callBack(i,idStr) idIndex = idIndex+2 idIndex = collectionJson.find(fieldName,idIndex,len(collectionJson)) ,从而重新构造了我所遵循的方法并解决了问题: >

GetComponent<AudioSource>().Play();

答案 1 :(得分:-1)

使用FindObjectOfType<AudioManager>().Play("CatchingPresent");时,自己导入脚本可以正常工作。尝试从编辑器重新导入脚本(右键单击项目文件夹>全部重新导入。这可能需要一段时间,具体取决于项目的大小)

要使用AudioManager.instance.Play("CatchingPresent");,您首先需要创建一个包含instance这样的静态变量(此变量只能作为一个单例,如果多个AudioManager位于现场):

public class AudioManager : MonoBehaviour
{
    //Create a static AudioManager that will hold the reference to this instance of AudioManager
    public static AudioManager Instance;
    public Sound[] sounds;

    //Assign Instance to the instance of this AudioManager in the constructor
    AudioManager()
    {
        Instance = this;
    }

    // Rest of the AudioManager code
}

这样做,然后使用其余代码对我也有用。