|
Hastur Pierterson
Soundscape Alchemist
Join date: 5 Jan 2006
Posts: 105
|
11-27-2006 11:52
Have a little issue with a script I'm trying to get working. I have an object that contains multiple sound files, the script is to play a random sound when an avatar walks on it. The problem is that when I use llSetSoundQueueing and collsion_start (or end) it triggers multiple collision events as (I believe) the avatar is still in transition across the prim. What do I use to throttle the multiple events so that only a single sound is triggered... I tried to use llMinEventDelay but without any luck. For instance, trigger a single sound, then pause/sleep/delay for 30 seconds before allowing another collision event. I'm prolly overlooking something very basic, but I reviewed the forums last night and the wiki but need some additional insight. Thanks in advance for any input. default { state_entry() { llSetSoundQueueing(TRUE); llVolumeDetect(FALSE);
} collision_start(integer total_number) { integer n = llGetInventoryNumber(INVENTORY_SOUND); integer i = llFloor(llFrand(n)); llPlaySound(llGetInventoryName(INVENTORY_SOUND, i), 1.0); } }
|
|
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
|
11-27-2006 12:56
From: Hastur Pierterson Have a little issue with a script I'm trying to get working. I have an object that contains multiple sound files, the script is to play a random sound when an avatar walks on it. The problem is that when I use llSetSoundQueueing and collsion_start (or end) it triggers multiple collision events as (I believe) the avatar is still in transition across the prim. What do I use to throttle the multiple events so that only a single sound is triggered... I tried to use llMinEventDelay but without any luck. For instance, trigger a single sound, then pause/sleep/delay for 30 seconds before allowing another collision event. I'm prolly overlooking something very basic, but I reviewed the forums last night and the wiki but need some additional insight. Thanks in advance for any input. default { state_entry() { llSetSoundQueueing(TRUE); llVolumeDetect(FALSE);
} collision_start(integer total_number) { integer n = llGetInventoryNumber(INVENTORY_SOUND); integer i = llFloor(llFrand(n)); llPlaySound(llGetInventoryName(INVENTORY_SOUND, i), 1.0); } }
Unless I am mistaken a collision_start event should only be triggered once for each AV/Object. Is the Object interacting with something else? A way around this would be to switch state on collision start, play the sound and then switch back after a delay default { state_entry() { }
collision_start(integer total_number) { state PlaySound; } }
state PlaySound { state_entry() { llSetTimerEvent(30); integer n = llGetInventoryNumber(INVENTORY_SOUND); integer i = llFloor(llFrand(n)); llPlaySound(llGetInventoryName(INVENTORY_SOUND, i), 1.0); }
timer() { llSetTimerEvent(0); state default; } }
I noticed you had llVolumeDetect(FALSE) in your orginal code. This is the default value so I was wondering why the code was there?
|
|
Hastur Pierterson
Soundscape Alchemist
Join date: 5 Jan 2006
Posts: 105
|
perfect!
11-27-2006 16:38
Thanks Newgate!
This worked perfectly. No, the AV would be walking on or through the prim causing the collisions. In my original attempts, it appeared that it would generate multiple events as the AV moved through this space. I had originally experimented with the llVolumeDetect from other forum recommendations and reviewing the wiki, I should have removed it from my posted sample.
I got this to work easily with a very thin phantom wall prim, but I'm not sure if there is a difference when attempting a similar scenario with a large prim being walked across.
Again, thanks for the pointers!
|
|
Joannah Cramer
Registered User
Join date: 12 Apr 2006
Posts: 1,539
|
11-27-2006 18:09
From: Hastur Pierterson What do I use to throttle the multiple events so that only a single sound is triggered... I tried to use llMinEventDelay but without any luck. For instance, trigger a single sound, then pause/sleep/delay for 30 seconds before allowing another collision event. Sleep and events can work in quite odd ways if i recall right. Alternative to state switching would be something like: integer no_sound_until; default { collision_start(integer total_number) { if( llGetUnixTime() < no_sound_until ) return;
integer n = llGetInventoryNumber(INVENTORY_SOUND); integer i = llFloor(llFrand(n)); llPlaySound(llGetInventoryName(INVENTORY_SOUND, i), 1.0); no_sound_until = llGetUnixTime() + 5; // ignore sound requests for 5 secs from now on } }
... it's not as elegant but on the upside allows to handle regular code in the meanitme rather than need it duplicated in the 'no sound' state ^^;;
|
|
Nynthan Folsom
Registered User
Join date: 29 Aug 2006
Posts: 70
|
12-01-2006 19:01
Putting a delay in the script is a solution although it would prevent the sound from playing if another av stepped on the prim. You could use a list to remember who collided. list colliding;
...
collide_start(integer count) { list nowcolliding; key detectedav; while(count--) { nowcolliding += [detectedav=llDetectedKey(count)]; if(llListFindList(colliding,[detectedav]) == -1) { // Trigger your sound } } colliding = nowcolliding; }
Of course be aware that lists are memory intensive so you might want to throttle the count.
|
|
Vares Solvang
It's all Relative
Join date: 26 Jan 2005
Posts: 2,235
|
12-01-2006 19:27
I've been making a "Star Trek" type door that uses volume detect to activate the door. I have noticed that is seems to be sending multiple collision_start messages as well. (I came up with the same solution that Newgate outlined.)
Is there something wrong with that function?
|