Trigger audio on door not working correctly

Hi other Craytars, I’m trying to add sound to a door for when it opens and closes. The adding sound is weird, because at first I can’t add it, I have to add something else, then select ‘revert property’ before I can actually add sound, but this is not my problem.

I used the tutorial: https://developer.crayta.com/obstacle-game-miniseries-5-polish/

When I try it out, it will make sound when the door opens, but not when it closes. And it will only make sound one time. If I open the door again, it won’t make the sound again.

I included the setting for the sound. Anyone know what my mistakes are? (with the door, I’m well aware of my lifes mistakes).

1 Like

I’ve had similar problems with adding sounds to doors and other triggered mechanism.

The Sound entity has a ‘active’ property, and when you change the value from false to true, the sound will start playing. If the sound asset in the Sound entity is a continuous loop, then you can switch the active property to false and true again, and the sound will stop and continue. But for sounds that are not looped, like the open door sound, this won’t work. Once the sound is finished playing, switching the active property won’t help.

I have found a work-around: you can re-set the Sound entity’s ‘sound’ property, i.e. the sound asset used by the Sound enity. By first clearing the sound’s sound property, and then setting it back to the original value, the entity’s state is modified in such a way that when you set the active propery to true again, it will play again.

You could modify the lockedDoor script like this:

instead of:
self.properties.sound.active = true

you could write:
– get sound entity and asset
local soundEntity = self.properties.sound
local soundAsset = soundEntity.sound
– stop the sound first, if it was running, and clear the sound asset
soundEntity.active = false
soundEntity.sound = nil
– re-set the asset and start playing
soundEntity.sound = soundAsset
soundEntity.active = true

(And if you use it frequently, better wrap it in a function)

You could also use sound assets in scripts directly, instead of Sound entities, but in the basic tutorials, Sound entities are used, and I think that is the nicest way to get beginners started, and the Sound Entity has some handy extra properties such as volume, pitch, range, fall-off, etc.

If only the Sound entity was a bit more helpful in these cases! I think i 'll put in a feature request for some handy functions on Sound entities to start, stop and restart sounds. Same for Effect entities, where non-looping effects like explosions will only run once. If these entities have a few extra functions, then users can connect these sounds and effects to events, without have to write scripts.

Actually, my solution above doesn’t always work, it seems… Haven’ t found a reliable way.

Sometimes, this also works:

self:Schedule(function()
    if soundEntity.active then
        soundEntity.active = false
        Wait()
    end
    soundEntity.active = true
end)

But it seems to depend on the sound asset you’ re using, how long it’s playing and how often it’s triggere :frowning: .

I ran into a similar issue with closing/opening door sounds (sometimes sounds will skip once, sometimes every third time, etc.) and after much experimentation this is how I made it to work reliably:

local DoorScript = {}

-- Script properties are defined here
DoorScript.Properties = {
	{name = "open", type = "boolean"},
	{name = "key", type = "entity"},
	{name = "openSound", type = "entity"},
	{name = "closeSound", type = "entity"},
	{name = "failSound", type = "entity"}
}

--This function is called on the server when this entity is created
function DoorScript:Init()
	self.timeToKeepOpenDoor = 4
	self.timeRemaining = 0
end

function DoorScript:Noise(noise)
	self:GetEntity():PlaySound(noise.sound)
	noise:Clone().active = true
end

function DoorScript:OnTick(deltaTime)
	if (self.properties.open and (self.timeRemaining <= 0)) then
		self:CloseDoor()
	else
		self.timeRemaining = self.timeRemaining - deltaTime
	end
end

function DoorScript:OpenDoor()
	--Print("Opening the door")
	self:Noise(self.properties.openSound)
	self:GetEntity():PlayAnimation("Open")
	self.properties.open = true
	self.timeRemaining = self.timeToKeepOpenDoor
end

function DoorScript:CloseDoor()
	--Print("Closing the door")
	self:Noise(self.properties.closeSound)
	self:GetEntity():PlayAnimation("Closed")
	self.properties.open = false
end

function DoorScript:OnInteract(player)
	--Print("Player '" .. player:GetName() .. "' is intracting with the door")
	if (not self.properties.key.ServerKeyScript:HasKey(player:GetName())) then
		Print("Player does not have proper key '".. self.properties.key:GetName() .."'")
		self:Noise(self.properties.failSound)
		return
	end
		
	if self.properties.open then
		self:CloseDoor()
	else
		self:OpenDoor()
	end
end

return DoorScript
1 Like