Skip to content

Instantly share code, notes, and snippets.

@kurtdekker
Created October 12, 2022 13:55
Show Gist options
  • Save kurtdekker/9f57ce71f696a31ebd464dd3c0640bf3 to your computer and use it in GitHub Desktop.
Save kurtdekker/9f57ce71f696a31ebd464dd3c0640bf3 to your computer and use it in GitHub Desktop.
Machinegun Sound (automatic gunfire) synthesis in Unity3D
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// @kurtdekker - synthesizes a cheesy machinegun sound
//
// DO NOT PUT THIS IN ANY SCENE!!!!
//
// Instead, simply use it by calling:
//
// MachinegunSound.Instance.SetRunning( true or false);
//
// That's it. You may call that every frame if you like.
//
// Be sure to turn off your gun in your OnDisable()
//
// I use this code in my Pilot Kurt game:
//
// Appstore: https://apps.apple.com/us/app/pilot-kurt/id1153921946
// GooglePlay: https://play.google.com/store/apps/details?id=com.plbm.flight1
// Android TV: https://play.google.com/store/apps/details?id=com.plbm.flight1tv
public class MachinegunSound : MonoBehaviour
{
private static MachinegunSound _Instance;
public static MachinegunSound Instance
{
get
{
if (!_Instance)
{
_Instance = new GameObject().AddComponent<MachinegunSound>();
_Instance.name = _Instance.GetType().ToString();
}
return _Instance;
}
}
bool running;
float volume;
public void SetRunning( bool _running)
{
running = _running;
// TODO: read your volume from your own sound volume settings here
volume = 1.0f;
// bring it down a bit
volume = volume / 4;
if (volume == 0)
{
running = false;
}
}
void Awake()
{
// fabricate a noise lookup table
int NoiseTableCount = 20000;
noiseTable = new float[NoiseTableCount];
for (int i = 0; i < noiseTable.Length; i++)
{
noiseTable[i] = Random.value;
}
var source = gameObject.AddComponent<AudioSource>();
source.bypassListenerEffects = true;
}
int noiseRover;
float[] noiseTable;
// how frequently do we rerun the envelope? (samples)
const int envelopeRate = 100;
int envelopeRover;
float[] envelope = new float[] {
1.0f,
1.0f,
1.0f,
1.0f,
0.8f,
0.8f,
0.7f,
0.6f,
0.5f,
0.4f,
0.3f,
0.2f,
0.1f,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};
void OnAudioFilterRead(float[] data, int channels)
{
if (!running)
{
envelopeRover = 0;
return;
}
int dataLen = data.Length / channels;
int n = 0;
while (n < dataLen)
{
float x = noiseTable[noiseRover];
x *= envelope[envelopeRover / envelopeRate];
x *= volume;
noiseRover++;
if (noiseRover >= noiseTable.Length)
{
noiseRover = 0;
}
envelopeRover++;
if (envelopeRover >= envelope.Length * envelopeRate)
{
envelopeRover = 0;
}
int channel = 0;
while (channel < channels)
{
data[n * channels + channel] = x;
channel++;
}
n++;
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// @kurtdekker - used to test MachinegunSound.cs
// To use:
// - drop this script on an empty GameObject
// - press and hold G when you want guns.
public class MachinegunTester : MonoBehaviour
{
void Start ()
{
Debug.Log( "Press/Hold the G key to fire guns");
}
void Update ()
{
bool onoff = Input.GetKey( KeyCode.G);
MachinegunSound.Instance.SetRunning( onoff);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment