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

贡萨洛·佩雷斯龚耀禄

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

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

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

带有我要销毁标签的gameObject具有音频源:

GameObject上带有特定标签的音频源


为了使声音在碰撞时播放,我首先创建了一个空的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-播放器与对象碰撞时要播放的声音。

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

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

            }
        }

由于该特定对象在碰撞时消失,因此它可以正常工作。现在,为了在播放器与带有标签的对象碰撞时随时播放声音“ CatchingPresent”,在这种情况下Present,我尝试将以下内容添加到ifOnCollisionEnter

  • FindObjectOfType<AudioManager>().Play("CatchingPresent");

但是我得到了错误:

The type or namespace name 'AudioManager' could not be found (are you missing a using directive or an assembly reference?)

  • AudioManager.instance.Play("CatchingPresent");

But I get the error:

The name 'AudioManager' does not exist in the current context

As all the compiler errors need to be fixed before entering the Playmode, any guidance on how to make the sound playing after a collision between the player and the gameObject with the tag Present is appreciated.


Edit 1: Assuming that it is helpful, here it goes the full ThirdPersonUserControl.cs:

using System;
using UnityEngine;
using UnityEngine.UI;
using UnityStandardAssets.CrossPlatformInput;

namespace UnityStandardAssets.Characters.ThirdPerson
{
    [RequireComponent(typeof (ThirdPersonCharacter))]
    public class ThirdPersonUserControl : MonoBehaviour
    {

        public Text countText;
        public Text winText;

        private int count;
        private ThirdPersonCharacter m_Character; // A reference to the ThirdPersonCharacter on the object
        private Transform m_Cam;                  // A reference to the main camera in the scenes transform
        private Vector3 m_CamForward;             // The current forward direction of the camera
        private Vector3 m_Move;
        private bool m_Jump;                      // the world-relative desired move direction, calculated from the camForward and user input.


        private void Start()
        {

            count = 20;
            SetCountText();
            winText.text = "";

            // get the transform of the main camera
            if (Camera.main != null)
            {
                m_Cam = Camera.main.transform;
            }
            else
            {
                Debug.LogWarning(
                    "Warning: no main camera found. Third person character needs a Camera tagged \"MainCamera\", for camera-relative controls.", gameObject);
                // we use self-relative controls in this case, which probably isn't what the user wants, but hey, we warned them!
            }

            // get the third person character ( this should never be null due to require component )
            m_Character = GetComponent<ThirdPersonCharacter>();
        }


        private void Update()
        {
            if (!m_Jump)
            {
                m_Jump = CrossPlatformInputManager.GetButtonDown("Jump");
            }
        }


        // Fixed update is called in sync with physics
        private void FixedUpdate()
        {
            // read inputs
            float h = CrossPlatformInputManager.GetAxis("Horizontal");
            float v = CrossPlatformInputManager.GetAxis("Vertical");
            bool crouch = Input.GetKey(KeyCode.C);

            // calculate move direction to pass to character
            if (m_Cam != null)
            {
                // calculate camera relative direction to move:
                m_CamForward = Vector3.Scale(m_Cam.forward, new Vector3(1, 0, 1)).normalized;
                m_Move = v*m_CamForward + h*m_Cam.right;
            }
            else
            {
                // we use world-relative directions in the case of no main camera
                m_Move = v*Vector3.forward + h*Vector3.right;
            }
#if !MOBILE_INPUT
            // walk speed multiplier
            if (Input.GetKey(KeyCode.LeftShift)) m_Move *= 0.5f;
#endif

            // pass all parameters to the character control script
            m_Character.Move(m_Move, crouch, m_Jump);
            m_Jump = false;
        }

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

                //FindObjectOfType<AudioManager>().Play("CatchingPresent");
                AudioManager.instance.Play("CatchingPresent");
            }
        }

        void SetCountText()
        {
            countText.text = "Missing: " + count.ToString();
            if (count == 0)
            {
                winText.text = "You saved Christmas!";
            }
        }
    }
}

Edit 2: Hierarchy in Unity:

Unity中的层次结构

Gonçalo Peres 龚燿禄

Reformulated the approach that I was following and solved the problem by simply adding an Audio Source to the ThirdPersonController (with the AudioClip that I wanted to call) and added GetComponent<AudioSource>().Play(); to the if statement as it follows:

void OnCollisionEnter(Collision other)
        {
            if (other.gameObject.CompareTag("Present"))
            {
                Destroy(other.gameObject);
                count = count - 1;
                SetCountText();
                GetComponent<AudioSource>().Play();
            }
        }

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Unity3D:计算具有特定游戏对象标签的孩子时出错

来自分类Dev

Unity3D:“翻译”对象的碰撞问题

来自分类Dev

当页面上出现特定文本时播放声音通知

来自分类Dev

仅当具有特定标签时才获取记录

来自分类Dev

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

来自分类Dev

Unity3d不喜欢碰撞

来自分类Dev

Unity3D 按需碰撞

来自分类Dev

构建Player:CommandInvokationFailure:Unity3d时出错

来自分类Dev

Rails充当标签,获取具有特定标签的所有相关对象

来自分类Dev

在Unity中使用Microsoft Azure文本语音转换时,播放声音的开头和结尾都会有断断续续的声音

来自分类Dev

播放声音时的静态噪音

来自分类Dev

轻按按钮时反复播放声音

来自分类Dev

播放声音时的静态噪音

来自分类Dev

按下按钮时播放声音

来自分类Dev

尝试播放声音时出错

来自分类Dev

在鼠标悬停时播放声音

来自分类Dev

当 <div> 可见时播放声音

来自分类Dev

当值改变时播放声音

来自分类Dev

GUI打开时播放声音

来自分类Dev

systemd没有播放声音

来自分类Dev

Mint 17.3没有播放声音

来自分类Dev

播放器与带标签的对象碰撞时消失

来自分类Dev

如何在 Unity3D C# 中旋转脊柱时检测碰撞?

来自分类Dev

在特定的声音设备Java上播放声音

来自分类Dev

Unity3D Player运动

来自分类Dev

仅运行具有特定标签或未标签的任务

来自分类Dev

在Unity3D中,碰撞检测还有其他选择吗?

来自分类Dev

在Windows 8中插入特定的USB驱动器时,如何播放声音?

来自分类Dev

在iOS上播放MPMusicPlayerController时AVAudioPlayer不播放声音