I've found, and experimented with this, which is just a simple piece of code which can be slapped onto any Unity3D game, pro or no, and it just works. If it's made in version 3.5 or higher.
But since you're reading this now, and at the time of creation Unity3D version 5 is nearing its release, I'm just gonna assume that you're using a more advanced version than 3.5.
Let me show you:
This is the code actually used to record and analyse the audio. Some comments are added along the way to help you understand it, but it shouldn't be too hard, the code is pretty self-explanatory.
Put it on an empty game object in Unity, name it MicrophoneInput and, that's it, really.
MicrophoneInput.cs:
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(AudioSource))]
public class MicrophoneInput : MonoBehaviour
{
public float sensitivity = 100; //Well, it's the sensitivity of the microphone, duh
public float loudness = 0; //This is what you'll probably want to use as the actual input
public float loudnessThreshold = 10; //This one is optional, it makes it so that not every sound triggers your input and is easier to use than adjusting sensitivity
public static MicrophoneInput microphoneInput;
// Use this for initialization
void Awake ()
{
if(microphoneInput != null)
{
Destroy(gameObject);
}
else
{
Object.DontDestroyOnLoad(gameObject);
microphoneInput = this;
}
}
void Start()
{
audio.clip = Microphone.Start(null, true, 10, 44100); //Here we grab the default microphone of the system the game is played on
audio.loop = true; // Set the AudioClip to loop
audio.mute = true; // Mute the sound, we don't want the player to hear it
while (!(Microphone.GetPosition(null) > 0)){} // Wait until the recording has started
audio.Play(); // Play the audio source!
}
void Update()
{
loudness = GetAveragedVolume() * sensitivity;
}
float GetAveragedVolume()
{
float[] data = new float[256];
float a = 0;
audio.GetOutputData(data,0);
foreach(float s in data)
{
a += Mathf.Abs(s);
}
return a/256;
}
}
Now, after this, you want to be able to use the newly acquired input data. Here's a simple script that uses the loudness, in combination with the left mouse button, as a trigger to fire.
GunController.cs:
using UnityEngine;
using System.Collections;
public class GunController : MonoBehaviour
{
private GameObject projectileClone;
[SerializeField] private MicrophoneInput microphone;
public float loudnessThreshold = 10;
private float fireDelay = 0.16f;
void Start ()
{
if (microphone == null) //What if I don't know where the microphone is?
{
microphone = GameObject.Find("MicrophoneInput").GetComponent(); //Nevermind, found it
}
loudnessThreshold = microphone.loudnessThreshold;
}
// Update is called once per frame
void Update ()
{
if (microphone.loudness > loudnessThreshold)
{
if (Input.GetMouseButton(0) && fireDelay <= 0)
{
Fire();
fireDelay = 0.16f;
}
}
fireDelay -= Time.deltaTime;
}
void Fire ()
{
if(projectile != null && gotGun)
{
projectileClone = (GameObject)GameObject.Instantiate(projectile, new Vector3(gameObject.transform.position.x,gameObject.transform.position.y,gameObject.transform.position.z), Quaternion.identity);
}
}
}
When using this system, one may find the need to be able to calibrate their loudness threshold. Here's an example script you can use.
LoudnessCalibration.cs:
using UnityEngine;
using System.Collections;
public class LoudnessCalibration : MonoBehaviour
{
[SerializeField] private MicrophoneInput microphone; //Shove that microphone in there
[SerializeField] private Timer timeTrigger; //In combination with a timer script, you can use the one below
[SerializeField] private TextMesh countdownText; //If you want to show a countdown before taking input
[SerializeField] private SpriteRenderer bar; //If you want to give some user-feedback on the loudness
// Use this for initialization
void Start ()
{
if (timeTrigger == null)
{
timeTrigger = gameObject.GetComponent();
}
microphone = GameObject.Find("MicrophoneInput").GetComponent(); //I found you!
bar.enabled = false;
}
// Update is called once per frame
void Update ()
{
if (bar.enabled)
{
if (!timeTrigger.triggered)
{
bar.transform.localScale = new Vector3(transform.localScale.x, 0.02f*microphone.loudness);
if (microphone.loudness > microphone.loudnessThreshold) //This picks the highest input and takes 20% off
{
microphone.loudnessThreshold = microphone.loudness*0.8f;
}
}
else
{
countdownText.text = "";
if (microphone.loudnessThreshold > 5) //The lowest possible threshold before continuing
{
//Do continue-stuff here
}
else
{
Application.LoadLevel(Application.loadedLevel);
}
}
}
else if (timeTrigger.triggered)
{
bar.enabled = true;
timeTrigger.duration = 3;
countdownText.text = "SHOUT!";
timeTrigger.triggered = false;
}
else
{
countdownText.text = "" + ((int) timeTrigger.duration + 1);
}
}
}
A simple timer script to use in conjunction with the calibration script.
using UnityEngine;
using System.Collections;
public class Timer : MonoBehaviour
{
[SerializeField] private bool destroyer = false;
[SerializeField] private bool triggerer = false;
[SerializeField] private bool surviveLoad = false;
[SerializeField] private bool quitGame = false;
public float duration;
[System.NonSerialized] public bool triggered = false;
void Awake ()
{
if (surviveLoad)
DontDestroyOnLoad(gameObject);
}
void Update ()
{
duration -= Time.deltaTime;
if (duration < 0)
{
Destroyer();
Triggerer();
QuitGame();
}
}
void Destroyer ()
{
if (destroyer)
{
Destroy(gameObject);
}
}
void Triggerer ()
{
if (triggerer)
{
triggered = true;
}
}
void QuitGame ()
{
if (quitGame)
{
Application.LoadLevel("menu");
}
}
}
Not that difficult when it's explained huh?
Just imagine all the different kinds of games you can make with this new tool on your programming belt!
Some other websites to check out, if you want some more examples:
http://code.tutsplus.com/tutorials/create-a-balloon-racing-game-in-unity-using-the-microphone--cms-21667
http://www.kaappine.fi/tutorials/using-microphone-input-in-unity3d/
Geen opmerkingen:
Een reactie posten