// NamedTriggerSoundOnce.cs using Simuspaces.Simulation; public class NamedTriggerSoundOnce : SimuScriptBase { protected override bool SyncTransformStateByDefault => false; public SceneObject AudioObject; public SceneObject TriggerObject; public string RequiredObjectName = ""; public bool IgnoreCase = true; public bool AllowPartialName = false; public float CooldownSeconds = 1.0f; public int AudioSourceIndex = 0; public bool IncludeAudioChildren = true; public bool IncludeTriggerChildren = true; public bool StopBeforePlay = true; public bool LogIgnoredTriggers = true; public bool LogAllTriggers = true; float nextAllowedTime; public override void Start() { if (HasSceneObject(TriggerObject)) { RegisterTrigger(TriggerObject, OnTriggered, null, IncludeTriggerChildren); Log("Registered trigger object=" + TriggerObject.ObjectId + ", requiredName='" + RequiredObjectName + "', audioObject=" + AudioTargetLabel() + "."); } else { RegisterTrigger(OnTriggered, null, IncludeTriggerChildren); LogWarning("TriggerObject is empty, using trigger colliders on this object. AudioObject=" + AudioTargetLabel() + "."); } } void OnTriggered(SVTriggerInfo info) { string objectName = info != null ? (info.ObjectName ?? "") : ""; string objectId = info != null ? (info.ObjectId ?? "") : ""; string username = info != null ? (info.Username ?? "") : ""; if (LogAllTriggers) Log("Trigger entered by name='" + objectName + "', id='" + objectId + "', user='" + username + "'."); if (!NameMatches(objectName)) { if (LogIgnoredTriggers) Log("Sound not played: trigger name '" + objectName + "' did not match RequiredObjectName='" + RequiredObjectName + "'."); return; } float now = Time.time; if (CooldownSeconds > 0f && now < nextAllowedTime) { if (LogIgnoredTriggers) Log("Sound not played: cooldown remaining " + (nextAllowedTime - now).ToString("0.00") + "s."); return; } if (!HasSceneObject(AudioObject)) { LogWarning("Sound not played: AudioObject is empty. Slot the audio object's go_ reference into AudioObject."); return; } if (StopBeforePlay) StopAudio(AudioObject, null, AudioSourceIndex, IncludeAudioChildren); PlayAudio(AudioObject, null, AudioSourceIndex, IncludeAudioChildren); nextAllowedTime = now + Mathf.Max(0f, CooldownSeconds); Log("Sound played. AudioObject=" + AudioObject.ObjectId + ", triggeredBy='" + objectName + "', cooldown=" + CooldownSeconds.ToString("0.00") + "s."); } bool HasSceneObject(SceneObject sceneObject) { return sceneObject != null && !System.String.IsNullOrWhiteSpace(sceneObject.ObjectId); } string AudioTargetLabel() { return HasSceneObject(AudioObject) ? AudioObject.ObjectId : "NULL"; } bool NameMatches(string objectName) { if (System.String.IsNullOrWhiteSpace(RequiredObjectName)) return true; objectName = objectName ?? ""; System.StringComparison comparison = IgnoreCase ? System.StringComparison.OrdinalIgnoreCase : System.StringComparison.Ordinal; return AllowPartialName ? objectName.IndexOf(RequiredObjectName, comparison) >= 0 : System.String.Equals(objectName, RequiredObjectName, comparison); } }