56 lines
2.1 KiB
GDScript
56 lines
2.1 KiB
GDScript
extends Node
|
|
## 最简近距离语音:按住 C(talk)采集麦克风 → 广播给所有对端 →
|
|
## 在说话者位置的 RaytracedAudioPlayer3D 回放。
|
|
## 距离衰减/声像由 3D 音频完成,墙体闷音、环境混响由 raytraced_audio 插件完成。
|
|
## 依赖:default_bus_layout.tres 的 mic 总线(静音 + AudioEffectCapture)、
|
|
## RaytracedReverb/RaytracedAmbient 总线(插件用)、player.tscn 根节点下的 Voice 节点。
|
|
|
|
@export var max_distance := 25.0
|
|
|
|
var _capture: AudioEffectCapture
|
|
var _voice_3d: RaytracedAudioPlayer3D
|
|
var _playback: AudioStreamGeneratorPlayback
|
|
|
|
|
|
func _ready() -> void:
|
|
_capture = AudioServer.get_bus_effect(AudioServer.get_bus_index("mic"), 0)
|
|
_voice_3d = RaytracedAudioPlayer3D.new()
|
|
var gen := AudioStreamGenerator.new()
|
|
gen.mix_rate = 48000.0 # 与 audio/driver/mix_rate 一致,否则变速变调
|
|
_voice_3d.stream = gen
|
|
_voice_3d.position = Vector3(0, 1.5, 0) # 嘴部高度
|
|
_voice_3d.max_distance = max_distance
|
|
add_child(_voice_3d)
|
|
if is_multiplayer_authority() and DisplayServer.get_name() != "headless":
|
|
var mic := AudioStreamPlayer.new()
|
|
mic.stream = AudioStreamMicrophone.new()
|
|
mic.bus = "mic"
|
|
add_child(mic)
|
|
mic.play()
|
|
# 监听器只建在本地玩家身上(多个监听器会互相抢 current)
|
|
var listener := RaytracedAudioListener.new()
|
|
listener.position = Vector3(0, 1.6, 0) # 头部高度
|
|
add_child(listener)
|
|
listener.owner = get_parent() # 插件的 ambient 计算会读 owner,代码创建的节点必须手动指定
|
|
else:
|
|
_voice_3d.play()
|
|
_playback = _voice_3d.get_stream_playback()
|
|
|
|
|
|
func _process(_delta: float) -> void:
|
|
if not is_multiplayer_authority() or _capture == null:
|
|
return
|
|
if not Input.is_action_pressed("talk"):
|
|
_capture.clear_buffer() # 松开时丢弃积压,避免下次开口带旧音频
|
|
return
|
|
var frames := _capture.get_buffer(_capture.get_frames_available())
|
|
if not frames.is_empty():
|
|
receive_voice.rpc(frames)
|
|
|
|
|
|
@rpc("any_peer", "call_remote", "unreliable_ordered", 1)
|
|
func receive_voice(frames: PackedVector2Array) -> void:
|
|
if not _playback:
|
|
_playback = _voice_3d.get_stream_playback()
|
|
_playback.push_buffer(frames)
|