class in Clatter.Unity
Inherits from MonoBehaviour
Singleton manager class for Clatter in Unity. To initialize Clatter in Unity, you must add a ClatterManager to the scene, at least two GameObjects with an ClatterObject
component, and an AudioListener.
Internally, ClatterManager stores data for each ClatterObject
in the scene and has a Clatter.Core.AudioGenerator
. When a collision occurs between two ClatterObject
components, the collision will be converted into a Clatter.Core.CollisionEvent
and announced to the ClatterManager, which will in turn feed it to the AudioGenerator (see AudioGenerator.AddCollision(collisionEvent)). ClatterManager then converts the generated audio into ImpactSound
or ScrapeSound
components, which will play the sound and then self-destruct.
ClatterManager can automatically update like any other MonoBehaviour class i.e. via Update() and FixedUpdate(). It might be convenient, especially to handle potential script execution order bugs, to manually update ClatterManager instead by setting auto == false. Either way, ClatterManager will call ClatterObject
.Initialize(id) and ClatterObject
.OnFixedUpdate() for each ClatterObject
in the scene.
In Clatter, audio is generated from both fixed values and random values; see the constructor for Clatter.Core.Modes
and Modes.AdjustPowers(). In most cases, you'll want the audio to be truly random. If you want to replicate the exact same audio every time you run your program, uncheck "Generate Random Seed" and then enter a seed.
For a minimal example scene, see the "Impact" scene in the ClatterUnityExamples project.
Name | Type | Description | Default Value |
---|---|---|---|
instance | ClatterManager |
Singleton instance. | |
auto | bool | If true, automatically update by calling Awake(), Update(), and FixedUpdate() (like an ordinary MonoBehaviour object). If this is false, you must manually update instead by calling instance.Awake(), instance.OnUpdate(), and instance.OnFixedUpdate(). | true |
adjustAudioSettings | bool | If true, adjust the global audio settings for better-quality audio. | true |
Name | Type | Description | Default Value |
---|---|---|---|
generateRandomSeed | bool | If true, generate a new random seed. | true |
seed | int | The random seed. Ignored if generateRandomSeed == true. | |
generator | AudioGenerator |
The audio generator. | |
onDestroy | Action | Invoked when this is destroyed. |
public void OnAwake()
Initialize the ClatterManager. If auto == true, this method is automatically called in Awake(). This method will find all ClatterObject
components in the scene and initialize them; see: ClatterObject
.Initialize(id). It will also initialize the internal AudioGenerator.
public void OnUpdate()
Call this once per frame to update ClatterManager. If auto == true, this method is automatically called in Update(). This method updates the internal Clatter.Core.AudioGenerator
(see AudioGenerator.Update()) as well as each ClatterObject
the scene; see ClatterObject
.OnUpdate().
public void OnFixedUpdate()
Call this once per physics frame to update ClatterManager. If auto == true, this method is automatically called in FixedUpdate(). This method updates each ClatterObject
the scene; see: ClatterObject
.OnFixedUpdate().
Create a Clatter scene in Unity purely from code. See the "Marbles" scene in ClatterUnityExamples.
using UnityEngine;
using Clatter.Core;
using Clatter.Unity;
using Random = System.Random;
// Drop lots of marbles, generating impact sounds.
public class Marbles : MonoBehaviour
{
// The diameter of a marble.
private const float DIAMETER = 0.013f;
// The spacing between the marbles.
private const float SPACING = 0.1f;
// The padded half-extent of the floor.
private const float EXTENT = 0.4f;
// The random seed.
public int seed;
private void Awake()
{
// Generate the floor.
GameObject floor = GameObject.CreatePrimitive(PrimitiveType.Cube);
floor.transform.localScale = new Vector3(1, 0.015f, 1);
floor.name = "floor";
// Generate audio from the floor.
ClatterObject f = floor.AddComponent();
f.impactMaterial = ImpactMaterialUnsized.metal;
f.autoSetSize = false;
f.size = 4;
f.amp = 0.5;
f.resonance = 0.2;
// Add the floor's Rigidbody and set the mass.
Rigidbody fr = floor.AddComponent();
fr.isKinematic = true;
fr.mass = 100;
// Create the random number generator.
Random rng = new Random(seed);
// Add marbles in a grid.
float z = -EXTENT;
while (z < EXTENT)
{
float x = -EXTENT;
while (x < EXTENT)
{
GameObject marble = GameObject.CreatePrimitive(PrimitiveType.Sphere);
// Set a random y value.
float y = 1.8f + (float)rng.NextDouble();
// Set the position.
marble.transform.position = new Vector3(x, y, z);
// Set the scale.
marble.transform.localScale = new Vector3(DIAMETER, DIAMETER, DIAMETER);
// Set a random color.
marble.GetComponent().material.color = new Color((float)rng.NextDouble(), (float)rng.NextDouble(), (float)rng.NextDouble(), 1);
// Add the Rigidbody.
Rigidbody mr = marble.AddComponent();
mr.mass = 0.03f;
// Add the audio data.
ClatterObject clatterObject = marble.AddComponent();
clatterObject.impactMaterial = ImpactMaterialUnsized.glass;
clatterObject.autoSetSize = false;
clatterObject.size = 0;
clatterObject.bounciness = 0.6f;
clatterObject.resonance = 0.05;
clatterObject.amp = 0.2;
x += SPACING;
}
z += SPACING;
}
// Add the ClatterManager.
GameObject go = new GameObject("ClatterManager");
ClatterManager cm = go.AddComponent();
cm.OnAwake();
}
}
Create a Clatter scene that listens for collision events. This example sets auto to False and manually updates ClatterManager from a separate script. This way, we can be certain that ClatterManager.OnAwake() will be invoked after the listener script awakens. See "CollisionListener" in ClatterUnityExamples.
using UnityEngine;
using UnityEngine.UI;
using Clatter.Core;
using Clatter.Unity;
// Listen for collisions and display their info in the UI. This example sets ClatterManager.auto to false in order to prevent script execution bugs.
public class CollisionListener : MonoBehaviour
{
// The UI text.
public Text text;
// The ClatterManager.
public ClatterManager clatterManager;
private void Awake()
{
clatterManager.generator.onImpact += OnCollision;
clatterManager.generator.onScrapeStart += OnCollision;
clatterManager.generator.onScrapeOngoing += OnCollision;
clatterManager.OnAwake();
}
private void OnCollision(CollisionEvent collisionEvent, Samples samples, Vector3d position, int audioSourceId)
{
if (collisionEvent.type != AudioEventType.none)
{
text.text = collisionEvent.primary.id + " " + collisionEvent.secondary.id + " " + collisionEvent.type;
}
}
private void Update()
{
clatterManager.OnUpdate();
}
private void FixedUpdate()
{
clatterManager.OnFixedUpdate();
}
}