How to make a master volume slider? [SOLVED]
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
How to make a master volume slider? [SOLVED]
I've looked around for info on this, but haven't found anything applicable in the documentation, but I feel like it must be doable. Does anyone know how to create a working master volume slider in Ren'Py? One separate from the music, SFX and voice sliders, which adjusts the baseline for all the volume channels.
As far as I can recall, most commercial VNs I've played have a master volume slider, but I'm not clear on how to implement one given that Ren'Py doesn't include it as a default function.
As far as I can recall, most commercial VNs I've played have a master volume slider, but I'm not clear on how to implement one given that Ren'Py doesn't include it as a default function.
Last edited by Desertopa on Wed Dec 02, 2020 10:53 am, edited 1 time in total.
- hell_oh_world
- Miko-Class Veteran
- Posts: 777
- Joined: Fri Jul 12, 2019 5:21 am
- Contact:
Re: How to make a master volume slider?
I guess you just combine the other channels.
Code: Select all
bar:
action [Preference("music volume"), Preference("sound volume"), Preference("voice volume")]
Re: How to make a master volume slider?
If I'm understanding what you're suggesting, this would create a slider which would simultaneously adjust all the other sliders, but what I'm looking to implement is a slider which acts as a multiplier to all the other sliders, so it adjusts the volume of all the channels up and down in the same proportion, while the other sliders can be used to adjust them relative to each other.
- hell_oh_world
- Miko-Class Veteran
- Posts: 777
- Joined: Fri Jul 12, 2019 5:21 am
- Contact:
Re: How to make a master volume slider?
Okay, sorry, I realized that my answer is entirely wrong. Guess I should not answer questions first thing in the morning. Anyways, this one is working.
EDIT
If the volume is involved, you can probably use renpy.game.preferences.volumes.get("name_of_mixer") to get the volume of the channel.
ANOTHER EDIT
Okay, tried to find a workaround, here's what I got.
then in your bars that adjust the music, sfx, voice, or any other mixers, you'll just use the bar value VolumeValue(mixer_name) instead of the Preference("mixer_name volume") value. this one is important, as the value object stores the last volume.
then like in my previous example, you'll just have to use the MasterVolumeValue() value in your bar that controls the master_volume.
One thing to note though, I observed, that this works if the bar is dragged and released, just clicking the bar to change the slider won't work. I'm guessing that this would require additional work with the adjustment object/bar value of the bar, but I don't know, might try to find some workaround though.
LAST EDIT (HOPEFULLY)
just replace the VolumeValue function in my example with this one.
Code: Select all
default persistent.master_volume = 0.0
init python:
def MasterVolumeValue():
return FieldValue(persistent, "master_volume", 1.0, action=Function(_changeVolumes))
def _changeVolumes():
renpy.run(
[
Preference("music volume", persistent.master_volume),
Preference("sound volume", persistent.master_volume),
Preference("voice volume", persistent.master_volume)
]
)
screen something:
bar:
value MasterVolumeValue()
Eh... Not sure if I'm getting it right, but what you want actually requires to get the current volume of each channel and multiply it with a multiplier? no? That would be tricky imo.but what I'm looking to implement is a slider which acts as a multiplier to all the other sliders, so it adjusts the volume of all the channels up and down in the same proportion, while the other sliders can be used to adjust them relative to each other.
If the volume is involved, you can probably use renpy.game.preferences.volumes.get("name_of_mixer") to get the volume of the channel.
ANOTHER EDIT
Okay, tried to find a workaround, here's what I got.
Code: Select all
default persistent.master_volume = 1.0
# add here the mixers that you want to be controlled and give them a starting value, sfx = sound
default persistent.last_volumes = dict(
music=1.0, sfx=1.0, voice=1.0
)
# if you want to set them by default to the current value of the mixer do below.
# init 3000:
# default persistent.last_volumes = dict(
# music=preferences.volumes.get("music", 0.0),
# sfx=preferences.volumes.get("sfx", 0.0),
# voice=preferences.volumes.get("voice", 0.0),
# )
# or
# default persistent.last_volumes = preferences.volumes.copy()
init python:
def MasterVolumeValue():
return FieldValue(persistent, "master_volume", 1.0, action=Function(_changeVolumes))
def VolumeValue(mixer):
volumes = preferences.volumes
return DictValue(volumes, mixer, 1.0, action=SetDict(persistent.last_volumes, mixer, volumes.get(mixer)))
def _changeVolume(mixer):
factor = persistent.master_volume
volume = persistent.last_volumes[mixer]
volume = max(min(volume * factor, 1.0), 0.0)
renpy.run(SetMixer("{}".format(mixer), volume))
def _changeVolumes():
for volume in persistent.last_volumes:
_changeVolume(volume)
Code: Select all
vbox:
text "Music Volume"
bar:
value VolumeValue("music")
vbox:
text "Sound Volume"
bar:
value VolumeValue("sfx")
vbox:
text "Voice Volume"
bar:
value VolumeValue("voice")
One thing to note though, I observed, that this works if the bar is dragged and released, just clicking the bar to change the slider won't work. I'm guessing that this would require additional work with the adjustment object/bar value of the bar, but I don't know, might try to find some workaround though.
LAST EDIT (HOPEFULLY)
Code: Select all
init python:
class VolumeValue(DictValue):
def __init__(self, mixer, *args, **kwargs):
DictValue.__init__(self, preferences.volumes, mixer, 1.0, *args, **kwargs)
self.mixer = mixer
def changed(self, value):
DictValue.changed(self, value)
persistent.last_volumes[self.mixer] = value
Re: How to make a master volume slider?
Sorry for the slow reply, I was having trouble implementing this myself, but a friend of mine was able to successfully troubleshoot it and get it working, so I can confirm that this did work.
-
- Regular
- Posts: 30
- Joined: Tue Jun 01, 2021 6:24 am
- Contact:
Re: How to make a master volume slider? [SOLVED]
For anyone else coming to this thread late, there is a much easier way to do this, via a rather arcane function:
renpy.music.set_volume(volume, delay=0, channel=u'music') link, which "Sets the volume of this channel, as a fraction of the volume of the mixer controlling the channel." There is also an alias for "sound" but none for "voice" - go figure!
So to make your master volume control, you only need to define one persistent variable in options.rpy:
Then the function:
And finally, call the function via an action in the bar or vbar code.
According to the documentation, this action is called " when the field has changed" so no need for special code to repeatedly call the function as the slider moves.
When I first started out trying to make a master volume control, I was surprised that it was so difficult and that there wasn't a built-in function to perform it. Turns out there is one, but as usual, it's hidden away in the weeds
renpy.music.set_volume(volume, delay=0, channel=u'music') link, which "Sets the volume of this channel, as a fraction of the volume of the mixer controlling the channel." There is also an alias for "sound" but none for "voice" - go figure!
So to make your master volume control, you only need to define one persistent variable in options.rpy:
Code: Select all
define persistent.audio_master = 1.0
Code: Select all
init python:
def setVolumes():
pam = persistent.audio_master
renpy.music.set_volume(pam)
renpy.sound.set_volume(pam)
renpy.music.set_volume(pam, channel="voice") #because there is no renpy.voice.set_volume function with a default channel
Code: Select all
vbar value FieldValue(persistent, "audio_master", range=1.0, style="slider", action=setVolumes)
When I first started out trying to make a master volume control, I was surprised that it was so difficult and that there wasn't a built-in function to perform it. Turns out there is one, but as usual, it's hidden away in the weeds
-
- Newbie
- Posts: 13
- Joined: Sun Aug 01, 2021 8:06 pm
- Contact:
Re: How to make a master volume slider? [SOLVED]
Still buggy.
The last code posted indeed works but the volume resets to 1.0 when reloading the game or returning to the main menu from the game. And I also found it not working when quickly clicking a button (it makes the button sound even if the vol its 0).
Would be nice a clean master volume.
The last code posted indeed works but the volume resets to 1.0 when reloading the game or returning to the main menu from the game. And I also found it not working when quickly clicking a button (it makes the button sound even if the vol its 0).
Would be nice a clean master volume.
-
- Regular
- Posts: 30
- Joined: Tue Jun 01, 2021 6:24 am
- Contact:
Re: How to make a master volume slider? [SOLVED]
Yes I have been trying to find a way to assign these values during init without success.
Best idea I've come up with so far is to write an alternative play function that includes a call to setVolumes.
I'm guessing, since renpy.music.set_volume seems to have no equivalent screen or standard renpy functions, that this is still a work in progress so hopefully will be more developed in future versions.
Best idea I've come up with so far is to write an alternative play function that includes a call to setVolumes.
I'm guessing, since renpy.music.set_volume seems to have no equivalent screen or standard renpy functions, that this is still a work in progress so hopefully will be more developed in future versions.
Who is online
Users browsing this forum: Ahrefs [Bot], Google [Bot]