public void Speak(ThingPart thingPart, string text, VoiceProperties properties) { if (voice == null) { try { voice = gameObject.AddComponent <WindowsVoice>() as WindowsVoice; voice.Init(); } catch (Exception exception) { voice = null; Log.Debug("Failed to initialize Windows Voice"); } } if (voice != null) { bool hasSurroundSound = false; Thing thing = thingPart.transform.parent.gameObject.GetComponent <Thing>(); if (thing != null) { hasSurroundSound = thing.hasSurroundSound; } Vector3 ourPosition = Managers.personManager.ourPerson.Head.transform.position; float distance = Vector3.Distance(ourPosition, thingPart.transform.position); const float maxDistanceToHear = 12.5f; const float startOfHearingFallOff = 2f; float relativeVolume = 1f; if (distance > startOfHearingFallOff && !hasSurroundSound) { relativeVolume = 1f - (distance - startOfHearingFallOff) / (maxDistanceToHear - startOfHearingFallOff); } const float generalVolumeAdjust = 0.5f; relativeVolume *= generalVolumeAdjust; if (properties == null) { properties = new VoiceProperties(); } VoiceProperties adjustedProperties = new VoiceProperties(); adjustedProperties.gender = properties.gender; adjustedProperties.volume = (int)((float)properties.volume * relativeVolume); adjustedProperties.pitch = properties.pitch; adjustedProperties.speed = properties.speed; if (adjustedProperties.volume > 0) { voice.Speak(text, adjustedProperties); } } }