Jump to content

Use multiple playSound for one sound file


jingzhi

Recommended Posts

Then it's strange, I can't tell why this script doesn't run good. It only works when it's playing the sound for one player only, when it plays for the second player the first player can not hear it anymore.

function engine_func() 
    local veh = getPedOccupiedVehicle (localPlayer) 
    local RPM = getVehicleRPM(veh) 
    setElementData(veh,"RPM",RPM) 
    if veh then 
        if getVehicleEngineState (veh) == true then 
            setSoundVolume(local_sound,1) 
            setSoundSpeed(local_sound, RPM * 2.5 / 10000) 
        else 
            if getSoundVolume(local_sound) == 1 then 
                setSoundVolume(local_sound,0) 
            end 
        end 
    else 
        destroyElement(local_sound) 
        removeEventHandler("onClientRender",root,engine_func) 
    end 
end 
  
addEventHandler ( "onClientVehicleEnter", getRootElement(), 
function() 
    if getElementModel ( source ) == 411 then 
        setWorldSoundEnabled(40,false) 
        local x,y,z = getElementPosition(source) 
        if vehicles[source] then vehicles[source] = nil end 
        local_sound = playSound3D(engine_sound, x, y, z, true) 
        setSoundVolume(local_sound,0) 
        attachElements(local_sound,source) 
        addEventHandler ( "onClientRender", getRootElement(), engine_func ) 
    end 
end) 
  
addEventHandler ( "onClientVehicleExit", getRootElement(), function() 
    if getElementModel(source) == 411 then 
        setWorldSoundEnabled(40,true) 
        destroyElement(local_sound) 
        removeEventHandler ( "onClientRender", getRootElement(), engine_func ) 
    end 
end) 

Link to comment
Then it's strange, I can't tell why this script doesn't run good. It only works when it's playing the sound for one player only, when it plays for the second player the first player can not hear it anymore.
function engine_func() 
    local veh = getPedOccupiedVehicle (localPlayer) 
    local RPM = getVehicleRPM(veh) 
    setElementData(veh,"RPM",RPM) 
    if veh then 
        if getVehicleEngineState (veh) == true then 
            setSoundVolume(local_sound,1) 
            setSoundSpeed(local_sound, RPM * 2.5 / 10000) 
        else 
            if getSoundVolume(local_sound) == 1 then 
                setSoundVolume(local_sound,0) 
            end 
        end 
    else 
        destroyElement(local_sound) 
        removeEventHandler("onClientRender",root,engine_func) 
    end 
end 
  
addEventHandler ( "onClientVehicleEnter", getRootElement(), 
function() 
    if getElementModel ( source ) == 411 then 
        setWorldSoundEnabled(40,false) 
        local x,y,z = getElementPosition(source) 
        if vehicles[source] then vehicles[source] = nil end 
        local_sound = playSound3D(engine_sound, x, y, z, true) 
        setSoundVolume(local_sound,0) 
        attachElements(local_sound,source) 
        addEventHandler ( "onClientRender", getRootElement(), engine_func ) 
    end 
end) 
  
addEventHandler ( "onClientVehicleExit", getRootElement(), function() 
    if getElementModel(source) == 411 then 
        setWorldSoundEnabled(40,true) 
        destroyElement(local_sound) 
        removeEventHandler ( "onClientRender", getRootElement(), engine_func ) 
    end 
end) 

No solution?

Link to comment

Create a table for storage sound elements. Also you must add an event which sets sound element to nil. (onClientPlayerQuit)

English isn’t my first language, so please excuse any mistakes.

  
function onClientPlayerQuit_Handler() 
if isElement(local_sound[source]) then 
      local_sound[source] = nil 
end 
end 
addEventHandler("onClientPlayerQuit", root, onClientPlayerQuit_Handler) 
  

  
local local_sound = {} 
  
function engine_func() 
    local veh = getPedOccupiedVehicle (localPlayer) 
    local RPM = getVehicleRPM(veh) 
    setElementData(veh,"RPM",RPM) 
    --edit #1 
    if veh then 
        if getVehicleEngineState (veh) == true then 
            setSoundVolume(local_sound[localPlayer],1) 
            setSoundSpeed(local_sound[localPlayer], RPM * 2.5 / 10000) 
        else 
            if getSoundVolume(local_sound[localPlayer]) == 1 then 
                setSoundVolume(local_sound[localPlayer],0) 
            end 
        end 
    else 
        destroyElement(local_sound[localPlayer]) 
        removeEventHandler("onClientRender",root,engine_func) 
    end 
end 
  
addEventHandler ( "onClientVehicleEnter", getRootElement(), 
function( thePlayer ) 
    if getElementModel ( source ) == 411 then 
        setWorldSoundEnabled(40,false) 
        local x,y,z = getElementPosition(source) 
        if vehicles[source] then vehicles[source] = nil end 
        --edit #2 
        local_sound[thePlayer] = playSound3D(engine_sound, x, y, z, true) 
        setSoundVolume(local_sound[thePlayer],0) 
        attachElements(local_sound[thePlayer],source) 
        addEventHandler ( "onClientRender", getRootElement(), engine_func ) 
    end 
end) 
  
addEventHandler ( "onClientVehicleExit", getRootElement(), function( thePlayer ) 
    if getElementModel(source) == 411 then 
        setWorldSoundEnabled(40,true) 
        --edit #3 
        --destroyElement(local_sound[thePlayer]) 
        --or 
        local_sound[thePlayer] = nil 
        removeEventHandler ( "onClientRender", getRootElement(), engine_func ) 
    end 
end) 
  

Link to comment
Create a table for storage sound elements. Also you must add an event which sets sound element to nil. (onClientPlayerQuit)

English isn’t my first language, so please excuse any mistakes.

  
function onClientPlayerQuit_Handler() 
if isElement(local_sound[source]) then 
      local_sound[source] = nil 
end 
end 
addEventHandler("onClientPlayerQuit", root, onClientPlayerQuit_Handler) 
  

  
local local_sound = {} 
  
function engine_func() 
    local veh = getPedOccupiedVehicle (localPlayer) 
    local RPM = getVehicleRPM(veh) 
    setElementData(veh,"RPM",RPM) 
    --edit #1 
    if veh then 
        if getVehicleEngineState (veh) == true then 
            setSoundVolume(local_sound[localPlayer],1) 
            setSoundSpeed(local_sound[localPlayer], RPM * 2.5 / 10000) 
        else 
            if getSoundVolume(local_sound[localPlayer]) == 1 then 
                setSoundVolume(local_sound[localPlayer],0) 
            end 
        end 
    else 
        destroyElement(local_sound[localPlayer]) 
        removeEventHandler("onClientRender",root,engine_func) 
    end 
end 
  
addEventHandler ( "onClientVehicleEnter", getRootElement(), 
function( thePlayer ) 
    if getElementModel ( source ) == 411 then 
        setWorldSoundEnabled(40,false) 
        local x,y,z = getElementPosition(source) 
        if vehicles[source] then vehicles[source] = nil end 
        --edit #2 
        local_sound[thePlayer] = playSound3D(engine_sound, x, y, z, true) 
        setSoundVolume(local_sound[thePlayer],0) 
        attachElements(local_sound[thePlayer],source) 
        addEventHandler ( "onClientRender", getRootElement(), engine_func ) 
    end 
end) 
  
addEventHandler ( "onClientVehicleExit", getRootElement(), function( thePlayer ) 
    if getElementModel(source) == 411 then 
        setWorldSoundEnabled(40,true) 
        --edit #3 
        --destroyElement(local_sound[thePlayer]) 
        --or 
        local_sound[thePlayer] = nil 
        removeEventHandler ( "onClientRender", getRootElement(), engine_func ) 
    end 
end) 
  

Not working, same problem

Link to comment
  • Moderators

Line 6 and 7. >local RPM = getVehicleRPM(veh)< >setElementData(veh,"RPM",RPM)<

Move after: if veh then

Line 19: Validate sound with isElement before destroying it.

Line 31: Validate the sound with if state, before setting it's volume etc.

Line 44: Makes no sense, nilling an location but losing access to the sound element.

But what I strongly recommend you, is not using the player as key of the table but the vehicles instead.

Use to add and remove from the table: https://wiki.multitheftauto.com/wiki/On ... ntStreamIn and https://wiki.multitheftauto.com/wiki/On ... tStreamOut

Link to comment
Line 6 and 7. >local RPM = getVehicleRPM(veh)< >setElementData(veh,"RPM",RPM)<

Move after: if veh then

Line 19: Validate sound with isElement before destroying it.

Line 31: Validate the sound with if state, before setting it's volume etc.

Line 44: Makes no sense, nilling an location but losing access to the sound element.

But what I strongly recommend you, is not using the player as key of the table but the vehicles instead.

Use to add and remove from the table: https://wiki.multitheftauto.com/wiki/On ... ntStreamIn and https://wiki.multitheftauto.com/wiki/On ... tStreamOut

Hello, I have made it as you said, don't know if it will work or not. What exactly do these events work? ( how to apply these 2 events in this very script ?)

Link to comment
  • Moderators

Those functions are for checking if elements are rendered by the GTA engine.

step 1) You add those two events to two functions.

step 2) On both of those functions. You validate the source element with the type "vehicle", using the function getElementType.

step 3) Use the event onClientElementStreamIn (+ function) to insert the a sound with the source as key of the table.

  
local sound = playSound3D(engine_sound, x, y, z, true) 
if sound  then 
 local_sound[source] =  sound 
 setElementParent(sound,source) 
end 

and you set the source element as parent of the sound element with setElementParent. (when the vehicle gets destroyed, the sound element is also gone)

step 4) Use the event onClientElementStreamOut (+ function) to receive the sound with the source as key of the table. Delete the sound with stopSound. And as last you nil a table location with the sound element as key.

local sound = local_sound[source]  
if isElement(sound) then 
 destroyElement(sound) 
end 
local_sound[source] = nil 

Extra info

The only thing you have to take a closer look at is that you have to check the table ones in while(maybe 2 hours?) for destroyed vehicles. This can be done with using getTickCount(). But this is extra, I don't think there are a lot of players playing longer than 10 hours. Or you can choose for onClientElementDestroy to replace the use of setElementParent.

Link to comment
Those functions are for checking if elements are rendered by the GTA engine.

step 1) You add those two events to two functions.

step 2) On both of those functions. You validate the source element with the type "vehicle", using the function getElementType.

step 3) Use the event onClientElementStreamIn (+ function) to insert the a sound with the source as key of the table.

  
local sound = playSound3D(engine_sound, x, y, z, true) 
if sound  then 
 local_sound[source] =  sound 
 setElementParent(sound,source) 
end 

and you set the source element as parent of the sound element with setElementParent. (when the vehicle gets destroyed, the sound element is also gone)

step 4) Use the event onClientElementStreamOut (+ function) to receive the sound with the source as key of the table. Delete the sound with stopSound. And as last you nil a table location with the sound element as key.

local sound = local_sound[source]  
if isElement(sound) then 
 destroyElement(sound) 
end 
local_sound[source] = nil 

Extra info

The only thing you have to take a closer look at is that you have to check the table ones in while(maybe 2 hours?) for destroyed vehicles. This can be done with using getTickCount(). But this is extra, I don't think there are a lot of players playing longer than 10 hours. Or you can choose for onClientElementDestroy to replace the use of setElementParent.

Thank you, that's very helpful

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...