在我們的環境中,常會有一些聲音與音效來提高我們遊戲的體驗,在實驗的過程中我們也會將聲音作為一種非視覺的回饋,告訴受試者完成某一件事情或是滿足某一個條件等,對我們來說非常重要。所以今天我將會透過一個簡單將兩物件接觸後觸發音效來演示音效產生的功能。 今天的實驗將會有趣也很簡單,那就讓我們開始吧XD
我們建置一個場景,ActiveRegion 是當我觸發的時候會發出一個觸發的聲音。 TargetPoint 是我要主動去觸發ActiveRegion 的物件。
我們先新增Empty Object 該命名為 AudioManager,並在 Component 內新增Audio Listener。
接著在我們的 Target 中增加 Audio Source,也就是物件上新增一個Component。我這邊是登入註冊該網站,裡面有免費的音效。
https://www.zapsplat.com/sound-effect-categories/
接著要將Mp3 檔案放置在該Audio Source中, AudioClip 上面。
接著在 AudioManager 上新增一個 Scripts ,我們這邊就叫做 Audio Feedback 。
接著在 Project 內新增一個 Sound.cs 的腳本,主要是控制該Sound Feedback 的控制。並不會使用到任何 Unity 內部的物件或是環境的元素,故不要去繼承 MonoBehaviour ,主要就只是去控制音量的大小與高低,並且讓我們環境可以儲存各種不同的音效。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Sound
{
public string name;
public AudioClip clip; // clip is the audio type
[Range(0f, 1f)]public float volume; // volume
[Range(.1f, 3f)]public float pitch; // pitch
[HideInInspector]
public AudioSource source;
}
public Sound[] sounds;
void Start()
{
foreach(Sound s in soundsArr)
{
s.source = gameObject.AddComponent<AudioSource>();
s.source.clip = s.clip;
s.source.volume = s.volume;
s.source.pitch = s.pitch;
}
}
// set the name and find the name of the sound effect
void playSoundEffect(string name)
{
Sound soundObj = Array.Find(soundsArr, sound => sound.name == name);
// find the name of the Audio Clip
soundObj.source.Play();
// play the sound effect
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class AudioFeedback : MonoBehaviour
{
public Sound[] soundsArr;
void Start()
{
foreach(Sound s in soundsArr)
{
s.source = gameObject.AddComponent<AudioSource>();
s.source.clip = s.clip;
s.source.volume = s.volume;
s.source.pitch = s.pitch;
}
}
// set the name and find the name of the sound effect
void playSoundEffect(string name)
{
Sound soundObj = Array.Find(soundsArr, sound => sound.name == name);
// find the name of the Audio Clip
soundObj.source.Play();
// play the sound effect
}
}
首先我們可以用之前學習到的 Collision關係來尋找兩個物件是否碰撞! 先將兩個物件 ActiveRegion 與 TargetPoint 各新增 Rigidbody。並把他們Rigidbody 的 Use Gravity 給取消勾選。
撰寫一個簡單的程式碼,如果當小球TargetPoint 觸發到 ActiveRegion 的話,就會有聲音的回饋,這時候我們就會需要勾選其中一個物件的 IsTrigger,因為我們不需要任何的物理碰撞! 我這邊勾選該 TargetPoint 中 Sphere Collider 的 IsTrigger
撰寫腳本,我們新增一個AwakeSound.cs 的腳本到我們TargetPoint 上面,首先我們撰寫當兩個物件接觸的瞬間的判斷。請記得如果要使用 OnTriggerEnter務必要使用在本身的物件上。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AwakeSound : MonoBehaviour
{
private void OnTriggerEnter(Collider collision){
if(collision.gameObject.name == "ActiveRegion")
{
Debug.Log("Trigger something!");
}
}
}
回到 Unity 執行後就會看到當我們TargetPoint 碰觸到物件Console 就會輸出 Trigger someting。
最後就是要去使用該聲音了,現在就回到你需要喚醒聲音的地方。
這邊就是需要去新增該聲音的地方。增添一行取出該物件並且去直接使用 Class 內部的方法。無須使用 Static。我們可以直接在Update 中使用。
// audio effect
FindObjectOfType<AudioFeedback>().Play("effect");
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
public class AwakeSound : MonoBehaviour
{
private void OnTriggerEnter(Collider collision){
if(collision.gameObject.name == "ActiveRegion")
{
Debug.Log("Play Sound!");
FindObjectOfType<AudioFeedback>().playSoundEffect("sound1");
}
}
}