HammeriteAudio
Autoloads. Inherits Node
Hammerite Audio runtime facade (autoload: HammeriteAudio).
Everything a game asks of acoustics is here: where its recordings are, what kinds of sound it has, how to play one, how to report a noise that has no sound of its own, how to open and shut a door, and how to bake a map's audio graph. The HammeriteAudioManager underneath is a per-map object that is built again for the next map, so nothing above needs to hold one. Hooks HammeriteMap3D directly -- no dependency on hammerite-editor or HammeriteMapEditor, so acoustic propagation works in builds that ship without the editor at all. Call integrate(map_3d) once per HammeriteMap3D you want acoustic propagation on, BEFORE assigning its map, so the manager exists before the map's entities build and ask for it:
HammeriteAudio.sounds.search_paths = ["res://sounds"]
HammeriteAudio.sound_types = load("res://sound_types.tres")
HammeriteAudio.integrate(map_3d)
map_3d.map = mapA map arriving with no baked graph is baked as it loads, so sound goes round corners from the first brush; bake() writes one deliberately, and the editor's Audio Portals tool is the same call. If hammerite-editor is also present and you want the audio graph authoring tool (zones/portals) and toolbar button, separately initialize HammeriteAudioEditorExtension -- see scripts/editor/audio_editor_extension.gd. The state itself lives in HammeriteAudioRuntime, which this delegates to - an autoload cannot be mentioned by anything that has to compile without a scene tree, which is every node in this addon.
Properties
Methods
| Returns | Method |
|---|---|
void | add_preset(preset: HammeriteAudioPreset) |
HammeriteAudioManager | get_manager(context: Node = null) |
int | play_one_shot(sound_file: String, position: Vector3, sound_type: StringName = &"", volume_db: float = 0.0, propagate: bool = true, context: Node = null) |
void | report_sound(sound_type: StringName, position: Vector3, source: Node = null) |
bool | set_portal_occlusion(portal_name: String, occlusion: float, context: Node = null) |
void | press_ear_to_portal(portal_name: String, gain_db: float, context: Node = null) |
void | take_ear_from_portal(context: Node = null) |
HammeriteAudioBakeReport | bake(map_3d: HammeriteMap3D) |
void | integrate(map_3d: HammeriteMap3D) |
Signals
graph_baked
signal graph_baked(map_3d: HammeriteMap3D, report: HammeriteAudioBakeReport)
Emitted after a map's audio graph has been baked, with what the bake made of it. Connect it to put the warnings wherever this game puts warnings.
Property descriptions
sound_types
var sound_types: HammeriteAudioSoundTypes
The game's sound-type table, assigned at startup. Hammerite has no opinion about what kinds of sound a game has - "footstep" is the game's vocabulary - so the loudness and carrying range of each come from here. Without one, sounds still propagate and are still heard, on the defaults in HammeriteAudioSoundTypes.
mix_settings
var mix_settings: HammeriteAudioMixSettings
How every map's sound is mixed: the muffle ladder, how weather fades on the way in, how far a route may be cached. Every value is a first guess to be tuned by ear, which is why they are authored data; see HammeriteAudioMixSettings. Without a table, the defaults there are used.
presets
var presets: HammeriteAudioPreset[]
The reverb characters a room can be given, read by every bake and by the brush inspector's dropdown; see HammeriteAudioRuntime.presets. Add a room of your own kind rather than editing the addon.
HammeriteAudio.add_preset(HammeriteAudioPreset.new(100, "vault", 0.4, 0.3, 0.95, 0.45, 1.0))Assigning a whole table replaces Hammerite's sixteen, so a game keeping them adds to them instead.
materials
var materials: HammeriteAudioMaterials
What each material does to sound, read by every bake; see HammeriteAudioMaterials. Add to the table it answers with, or assign one of your own.
HammeriteAudio.materials.add_material(HammeriteAudioMaterial.new(
"oak", 0.6, 0.4, 22.0, 0.45, HammeriteAudioMaterial.Category.WOOD))
material_resolver
var material_resolver: Callable
Which material a texture IS; see HammeriteAudioRuntime.material_resolver. The game's question rather than Hammerite's, because a texture name is geometry's and what it means is the level author's.
HammeriteAudio.material_resolver = func(texture: String) -> StringName:
return my_surfaces.material_of(texture)
sounds
var sounds: HammeriteAssetLibrary
Where a sound's name becomes a recording: a name such as doors/creak.ogg, found in the search paths given here or in a source the game adds.
HammeriteAudio.sounds.search_paths = ["res://sounds"]Empty until the game says where its audio is: with neither a search path nor a source, no sound resolves and every play reports No sound called ....
ambient_resolver
var ambient_resolver: Callable
What an ambience id sounds like; see HammeriteAudioRuntime.ambient_resolver.
ambient_bus
var ambient_bus: StringName
The bus rooms' ambience plays on; see HammeriteAudioRuntime.ambient_bus.
Method descriptions
add_preset()
func add_preset(preset: HammeriteAudioPreset) -> void
Add one reverb character to presets, replacing whatever had its id; see HammeriteAudioRuntime.add_preset().
get_manager()
func get_manager(context: Node = null) -> HammeriteAudioManager
The HammeriteAudioManager that applies to context, or null if there is none yet. For the handle API (HammeriteAudioManager.create_positional_sound() and the rest), which is the layer below this one. Everything else a game needs is on this autoload, and asking per call rather than holding what this returns is the difference between a door that still works after the next map and one that does not. Resolved by walking up from context to the HammeriteMap3D it lives under, since a node inside a map belongs to that map's acoustics. A node outside any map - a player parented to the scene root, which is the normal arrangement - falls back to the only manager there is, and says so rather than guessing when there are several.
play_one_shot()
func play_one_shot(sound_file: String, position: Vector3, sound_type: StringName = &"", volume_db: float = 0.0, propagate: bool = true, context: Node = null) -> int
Play a sound once at a point in space and forget about it. For noises with no object behind them - an impact, a sound whose emitter is about to be freed - where holding a handle would be bookkeeping for something that ends in half a second. The manager releases the sound once it has played through. Returns the handle, in case the caller wants to stop it early; it is valid only until the sound finishes. Use an HammeriteAudioEmitter3D for anything that repeats or moves.
report_sound()
func report_sound(sound_type: StringName, position: Vector3, source: Node = null) -> void
Report a noise that has no sound of its own. For the cases where the audible and the audible-to-gameplay come apart: a noise the player is meant to make but not hear themselves, or one whose audio is played by some other system. Plain sounds do not need this - an HammeriteAudioEmitter3D with a HammeriteAudioEmitter3D.sound_type, or play_one_shot() with one, reports itself.
set_portal_occlusion()
func set_portal_occlusion(portal_name: String, occlusion: float, context: Node = null) -> bool
Open or shut the opening named portal_name: 0 is open, 1 costs the opening its authored closed attenuation, and in between is ajar. Returns whether anything carries that name. The call a door entity makes. Name an opening with the Audio Portals tool; the name lives on the face it is punched from, so it survives a recompile, and hammerite-nav reads the same one.
HammeriteAudio.set_portal_occlusion("cell_door", 1.0, self)
press_ear_to_portal()
func press_ear_to_portal(portal_name: String, gain_db: float, context: Node = null) -> void
Press the player's ear to the opening named portal_name: what comes through it plays gain_db louder, and nothing else changes. Listening at a door. This is what is PLAYED. What the player's own HammeriteAudioReceiver3D hears is its HammeriteAudioReceiver3D.press_ear_to_portal(), so captions can follow the ear too.
take_ear_from_portal()
func take_ear_from_portal(context: Node = null) -> void
Undo press_ear_to_portal(): nothing is heard louder through any opening.
bake()
func bake(map_3d: HammeriteMap3D) -> HammeriteAudioBakeReport
Bake map_3d's audio graph from the world it has compiled, and hear it through the result from the next frame on. For a map rebaked while it is being played - a wall knocked through, a room added - and for a game that would rather bake deliberately than leave it to the load. The map keeps its graph, so the bake is saved with it, and what the author wrote (room presets, openings' names and their standing occlusion) survives. Without a scene tree - a headless or CI bake - call HammeriteAudioRuntime.bake() with the map itself.
integrate()
func integrate(map_3d: HammeriteMap3D) -> void
Wires up automatic HammeriteAudioManager injection for the given HammeriteMap3D.