消音(ミュート)ボタンを作りたい

80 views
Skip to first unread message

sola

unread,
Sep 6, 2025, 5:53:59 AM (4 days ago) Sep 6
to 宴ユーザーグループ

宴のバージョン:宴4.2.2
UnityのバージョンとOS:Unity6000.1.16f1 Mac
Unityの習熟度:初心者

お世話になっております。

シーン回想中やメインゲーム画面内にBGMやAmbienceなど全ての音声をミュートして
再度押すとミュートが解除されるボタンを作りたいです。

可能でしたらご教示お願い致します。

マッドネスラボ

unread,
Sep 6, 2025, 9:44:58 AM (4 days ago) Sep 6
to 宴ユーザーグループ
単純に安定的にオンオフする機能は存在しないので、
既存のサウンド系機能のなんらかのボリュームを操作することになります。

  1. ミュート状態をセーブさせるか、
  2. 動画(Videoコマンド等)で音声も使っている場合その音声もミュートするか
  3. デフォルトのUIにあるコンフィグのマスターボリュームも操作するか

によって、実装方法が違います。
1をやるならセーブデータの拡張も必要で、
2と3を両方やろうとすると、コンフィグ画面の改造も必要になります。
さしあたって、どちらでしょうか。


2025年9月6日土曜日 18:53:59 UTC+9 sola:

sola

unread,
Sep 6, 2025, 10:13:40 AM (4 days ago) Sep 6
to 宴ユーザーグループ
1.ミュート状態のセーブは考えてないです。
2.はい。ビデオオブジェクトの音声もミュートさせたいです。
3.デフォルトUIのコンフィグのマスターボリュームはそのままで実装可能なら
そちらでお願いしたいです。

以上の場合はいかがでしょうか?

2025年9月6日土曜日 22:44:58 UTC+9 マッドネスラボ:

マッドネスラボ

unread,
Sep 6, 2025, 10:57:00 AM (4 days ago) Sep 6
to 宴ユーザーグループ
すみません。間違いでした。
Unityにミュート機能そのものはないため、マスターボリューム(全体の音量)を0と1で切り替えることで実装することになります。
3と2は併存するのが結構難しいです。

2がなければ、Unityのプロジェクト設定のマスターボリュームを使用します。
(現状だと、ビデオはUnityのプロジェクト設定のマスターボリュームの影響を受けない形になっているため)

3がなければ、宴固有のマスターボリュームを使用します。
この場合、逆に自動的にセーブされてしまいます。

2と3を両方やろうとすると、2つのやり方があります。


やり方1 Unityプロジェクトのマスターボリュームの値(AudioListener.volume)をミュートに使う

ビデオの音声も、Unityのプロジェクト設定のマスターボリュームの影響を受けることもできるように、宴のソースコードの内部を更新する。
この場合、ビデオの音声再生がOS直接の再生ではなくなり、Unityのサウンド機能を通して行うようになります。
一応Unityの仕様としては可能なはずなのですが、ビデオ機能は非常に不安定なので、それで安定的に動作するかは私にもわかりません。
また、Unityプロジェクト全体の値のため、ほかでこの値を使用している場合は、機能が衝突してしまい不正な動作をします。

やり方2 宴固有のマスターボリュームの値(AdvEngine.Config.SoundMasterVolume)をミュートに使う
宴固有のマスターボリュームをミュート状態の場合は0にします。
コンフィグ画面でのマスターボリュームのUI操作に対しての仕様を決める必要があります。



2025年9月6日土曜日 23:13:40 UTC+9 sola:

マッドネスラボ

unread,
Sep 6, 2025, 11:17:29 AM (4 days ago) Sep 6
to 宴ユーザーグループ
コンフィグのUIからマスターボリュームを操作しない(マスターボリュームのUIバーを削除する)のであれば、
次のようなコンポーネントを作成し、オンオフのToggleボタンに設定するだけで可能だと思います。

ss_1089.png

やり方2の宴固有のマスターボリュームを使用するミュートのサンプル(マスターボリュームは他では使用できなくなる)


using UnityEngine;
using UtageExtensions;
using UnityEngine.UI;

namespace Utage
{
    public class Sample : MonoBehaviour
    {
        public AdvEngine Engine => this.GetAdvEngineCacheFindIfMissing(ref engine);
        [SerializeField] protected AdvEngine engine;
        [SerializeField] Toggle toggle;
       
        // ミュート状態かどうか
        public bool IsMute => Engine.Config.SoundMasterVolume <= 0f;
       
        void Awake()
        {
            toggle.onValueChanged.AddListener(SetMute);
        }
       
        void OnEnable()
        {
            toggle.isOn = IsMute;
        }

        // ミュートのオンオフ設定
        public void SetMute(bool mute)
        {
            Engine.Config.SoundMasterVolume = mute ? 0.0f : 1.0f;
        }
       
        // ミュートのオンオフ切り替え
        public void ToggleMute()
        {
            SetMute(!IsMute);
        }
    }
}
2025年9月6日土曜日 23:57:00 UTC+9 マッドネスラボ:

sola

unread,
Sep 6, 2025, 11:39:37 AM (4 days ago) Sep 6
to 宴ユーザーグループ
ご回答とサンプルありがとうございます!
コンフィグからマスターボリュームがなくなるというデメリットはありますが
実装は簡単そうです。

ただ当初の理想としていたものだと「やり方1」になってしまいます。
ビデオ機能は非常に不安定ということで自分のプロジェクトで不具合が出る可能性もありますが、試してみたい気持ちもあるので「やり方1」の方法も教えて頂くことは可能でしょうか?

2025年9月7日日曜日 0:17:29 UTC+9 マッドネスラボ:

sola

unread,
Sep 6, 2025, 11:51:29 AM (4 days ago) Sep 6
to 宴ユーザーグループ
すいません。
色々考えましたが実装が簡単そうで安定なので、教えていただいた「やり方2」の方法で進めたいと思います。
ご回答頂き誠にありがとうございました!

2025年9月7日日曜日 0:39:37 UTC+9 sola:

マッドネスラボ

unread,
Sep 6, 2025, 12:46:54 PM (4 days ago) Sep 6
to 宴ユーザーグループ
おもったよりも手軽に、「やり方1」のほうができそうだったので一応お伝えします。

宴の内部コードの更新が必要なので、添付のパッケージファイルを適用してください。
(ダウンロードした添付ファイルの拡張子が *. gzになっている場合は、*.unitypackageに変えてからプロジェクトに適用してください)
この変更は、次回の宴のアップデートにも反映させる予定です。

パッケージを適用すると、AdvEngine >  VideoManagerオブジェクトのAdvVideoManagerコンポーネントに「UseAudioListenerVolume」という項目が追加されるので、これをオンにしてください。
ss_1092.png
これをオンにすると、ビデオの音にもUnityプロジェクトのボリューム(AudioListener.volume)が適用されます。

先ほど、 >ビデオの音声再生がOS直接の再生ではなくなり と書いたのですが、このやり方だと難しそうだったので、別のやり方をしました。
ボリューム値のみ適用してビデオの音声再生の仕組み自体は変更してません。
なので、この変更が原因で不安定になることはないと思います。


ミュート処理のサンプルコードは以下のようになります。
使い方は先ほどと同じで、オンオフのToggleボタンオブジェクトを設定してください。

using UnityEngine;
using UnityEngine.UI;

namespace Utage
{
    //Unityのプロジェクト設定のボリューム(AudioListener.volume)を使ってミュートを制御するサンプル
    public class Sample : MonoBehaviour
    {
        //ミュート切り替えのToggleボタン

        [SerializeField] Toggle toggle;
       
        // ミュート状態かどうか
        public bool IsMute => AudioListener.volume <= 0f;

       
        void Awake()
        {
            toggle.onValueChanged.AddListener(SetMute);
        }
       
        void OnEnable()
        {
            toggle.isOn = IsMute;
        }

        // ミュートのオンオフ設定
        public void SetMute(bool mute)
        {
            AudioListener.volume = mute ? 0.0f : 1.0f;

        }
       
        // ミュートのオンオフ切り替え
        public void ToggleMute()
        {
            SetMute(!IsMute);
        }
    }
}


また、Unityプロジェクトのボリューム値は、
プログラム上では、AudioListener.volume
エディタ上でのデフォルト値は、ProjectSettings >  Audio > Global Volumeの値になります。
ss_1094.png

デフォルト値は1なので、基本的にはそのままにしてください。


2025年9月7日日曜日 0:51:29 UTC+9 sola:
VideoAudioVolume.unitypackage

sola

unread,
Sep 6, 2025, 8:05:57 PM (4 days ago) Sep 6
to 宴ユーザーグループ
「やり方1」での方法も教えて頂きありがとうございます!
早速試した所、無事問題なく実装できました。

ただ、ビデオオブジェクトに関してはAmbienceVolumeとして再生したかったので
AdvVideoManager内を下記のようにBgmVolumeから直接書き換えたのですが「宴」のアップデートの度に書き換えないといけないです。
お手数ですがoverrideする方法もご教授願えますでしょうか?

//ビデオ用のボリューム値を取得
public virtual float GetVideAudioVolume()
{
//Ambienceとマスターボリュームの値を掛け合わせたものを基本とする
float volume = Engine.SoundManager.AmbienceVolume * Engine.SoundManager.MasterVolume;
if (UseAudioListenerVolume)
{
//必要に応じてAudioListenerのボリュームも掛け合わせる
volume *= AudioListener.volume;
}
return volume;
}

2025年9月7日日曜日 1:46:54 UTC+9 マッドネスラボ:

マッドネスラボ

unread,
Sep 6, 2025, 8:54:35 PM (4 days ago) Sep 6
to 宴ユーザーグループ
既存のコンポーネントのメソッドをoverrideするには、C#の継承という仕組みを使います。

通常Unityのコンポーネントは
class クラス名 :  MonoBehaviour 
と書きます。(つまり通常はMonoBehaviour を継承しているというのがUnityの基本的な仕組みです)

独自のコンポーネントを継承する場合は
class 継承した新しいクラス名 : 継承元のクラス名
と書く形になります。


今回で言えば、下記のようにAdvVideoManagerを継承したAdvVideoManagerOverride という新しいコンポーネントを作って下さい。
ファイル名も新しい名前(AdvVideoManagerOverride )と同じ名前にしてください。

using UnityEngine;

namespace Utage
{
public class AdvVideoManagerOverride : AdvVideoManager
{
#if !UTAGE_DISABLE_VIDEO
//ビデオ用のボリューム値を取得
public override float GetVideAudioVolume()
{
//AmbienceVolumeとマスターボリュームの値

float volume = Engine.SoundManager.AmbienceVolume * Engine.SoundManager.MasterVolume;
if (UseAudioListenerVolume)
{
//必要に応じてAudioListenerのボリュームも掛け合わせる
volume *= AudioListener.volume;
}
return volume;
}
#else
#endif
}
}

ちょっとややこしいのですが、#if !UTAGE_DISABLE_VIDEO などとなっているのは、ビデオ機能そのものを一切使用しない設定がしてある場合に対応するためのかなり特殊なケースです。
(通常の継承やoverrideではこのような書き方はしないです)



継承したコンポーネントを作成したら、シーン内で使用している従来のコンポーネントを差し替えます。
AdvEnine > VideoManagerオブジェクトに、
・新しく作ったコンポーネントをAddComponent
・元からあったAdvVideoManageコンポーネントを削除します。(削除したいコンポーネント名で右クリックか、右上の︙アイコンから、「Remove Component」で削除できます)
ss_1095.png

このように、新しいコンポーネントだけ残るようにしてください
ss_1096.png

コンポーネントを差し替えた後、
他のコンポーネントとから従来のコンポーネントを参照していたものがあった場合、Missingになっているのでそれを設定しなおします。

今回で言えば、AdvEnine > GraphicManagerオブジェクトのAdvGraphicManagerコンポーネントの「Video Manager」の項目です。
ss_1097.png
( AdvGraphicManager のこの部分に関しては、実は設定しなくても実行時に自動的設定されるのですが、Missingのままだと不具合と見分けづらくなるので設定しなおしておいたほうが良いです)

今回は一か所だけでよいのですが、継承をする際にコンポーネントを付け替えた後は、このように他のオブジェクトの参照を設定をしなおさないといけないので、
どこから参照されているかをみわけるのが少し大変かもしれません。
(参照をしなおさないですむようにコンポーネントを差し替える裏技もあるのですが、Unity公式の操作ではないため動作保証が怪しいのでここでは割愛します)



2025年9月7日日曜日 9:05:57 UTC+9 sola:

sola

unread,
Sep 6, 2025, 9:12:33 PM (4 days ago) Sep 6
to 宴ユーザーグループ
ご説明ありがとうございます。
無事overrideでの実装と動作確認できました!
確かにコンポーネントによっては参照先の見直しも必要なため伺ってよかったです。

手厚いご対応誠にありがとうございました。

2025年9月7日日曜日 9:54:35 UTC+9 マッドネスラボ:
Reply all
Reply to author
Forward
0 new messages