KAGEX拡張例(kag.addTag)

前回はdoCommand()を使ってワールド拡張のタグを呼び出す方法を紹介しましたが、もっといい方法を教えてもらったので紹介します。

kag.addTag()という関数を使うとコンダクタに次のタグを直接登録できます。まずは実際の使用例です。

function showStage() {
    // @stage stage=道路 stime=昼 fade=1500 sync というタグを次のタグとして登録
    kag.addTag("stage", %[ stage:"道路", stime:"昼", fade:"1500", sync:"true" ]);
}

function showStage2() {
    // @道路 夜 fade=1500 nosync というタグを次のタグとして登録
    kag.addTag("道路", %[ 夜:"true", fade:"1500", nosync:"true" ]);
}

function flashStage() {
    // @stage hide fade=1000 sync というタグを次のタグとして登録
    kag.addTag("stage", %[ hide:"true", fade:"1000", sync:"true"]);

    // @stage show fade=1000 sync というタグを次のタグとして登録
    kag.addTag("stage", %[ show:"true", fade:"1000", sync:"true"]);
}
@linemode mode=vn

@eval exp="showStage()"
道路(昼)の背景を表示しました。

@eval exp="showStage2()"
道路(夜)の背景を表示しました。

@eval exp="flashStage()"
背景を点滅しました。

Override.tjsで定義した関数(showStage, showStage2)を[eval]タグで呼び出しています。関数の定義は[iscript][endscript]を使っても問題ありません。

kag.addTagには第1引数としてタグ名、第2引数として属性が入った辞書配列を渡します。

辞書配列の値はすべて文字列になるので注意してください。つまり、 show:true ではなく show:”true” です。大抵の場合問題になりませんが、稀に文字列でないと駄目な事もあるので必ず文字列にしておくといいです。

showStage2()のように省略記法も使えます。ksスクリプトで属性値を省略したときはtrueになるので、タグで省略されている部分は辞書配列上で”true”を渡しています。

flashStage()のように2つ以上続けて登録もできます。先に登録されたものから順に実行されます。

解説が長くなってしまうので、kag.addTagのもう少し詳しい解説は次回の記事に続きます。

KAGEX拡張例(doCommand)

KAGではkag.tagHandlers.ch(%);のようにkag.tagHandlersを使ってTJSからタグが実行できました。KAGEXの場合、同じ方法で呼び出せるタグもありますが、最もよく使うであろうワールド拡張系のタグは呼び出せません。いくつか例を挙げます。

キャラクタオブジェクト

[char]タグのコマンドはキャラクタオブジェクト(world_object.env.characters[“キャラ名”])を経由して呼び出します。

// @しおり face=怒 と同じ動作をさせる例
world_object.env.characters["しおり"].doCommand("face", "怒", %[]);
world_object.env.updateAll();

world_object.env.characters[“キャラ名”].doCommand(“属性名”, “属性値”, %[]);という形で大体は呼び出せます。その次の行のworld_object.env.updateAll();も必須です。一行目の段階では内部の状態が変更されただけで画面上には反映されません。updateAll()で初めて画面上の表情も変更されます。

2つ以上のコマンドを実行したい場合はupdateAllは最後に付けておけばいいです。

// @しおり face=怒り xpos=100 と同じ動作をさせる例
world_object.env.characters["しおり"].doCommand("face", "怒", %[]);
world_object.env.characters["しおり"].doCommand("xpos", "100", %[]);
world_object.env.updateAll();

背景オブジェクト

[stage]タグのコマンドは背景オブジェクト(world_object.env.stage)を経由して呼び出します。

// @stage stage=道路 と同じ動作をさせる例
world_object.env.stage.doCommand("stage", "道路", %[]);
world_object.env.updateAll();

world_object.env.stage.doCommand(“属性名”, “属性値”, %[]);という形になります。その他は[char]の場合と同様なので説明は省略します。

イベントオブジェクト

[evant]タグのコマンドはイベントオブジェクト(world_object.env.event)を経由して呼び出します。

// @event file=event1 と同じ動作をさせる例
world_object.env.event.doCommand("file", "event1", %[]);
world_object.env.updateAll();

world_object.env.event.doCommand(“属性名”, “属性値”, %[]);という形になります。その他は[char]の場合と同様なので説明は省略します。

環境レイヤオブジェクト

[layer]タグのコマンドは環境レイヤオブジェクト(world_object.env.layers[“レイヤ名”])を経由して呼び出します。

// @レイヤ hide と同じ動作をさせる例
world_object.env.layers["レイヤ"].doCommand("hide", "true", %[]);
world_object.env.updateAll();

world_object.env.layers[“レイヤ名”].doCommand(“属性名”, “属性値”, %[]);という形になります。その他は[char]の場合と同様なので説明は省略します。

環境オブジェクト

[env]タグのコマンドは環境オブジェクト(world_object.env)を経由して呼び出します。

// @env contrast=-255 と同じ動作をさせる例
world_object.env.doCommand("contrast", "-255", %[]);
world_object.env.updateAll();

world_object.env.doCommand(“属性名”, “属性値”, %[]);という形になります。その他は[char]の場合と同様なので説明は省略します。

BGMオブジェクト

[bgm]タグのコマンドはBGMオブジェクト(world_object.env.bgm)を経由して呼び出します。

// @bgm play=bgm01 と同じ動作をさせる例
world_object.env.bgm.doCommand("play", "bgm01", %[]);
world_object.env.updateAll();

world_object.bgm.doCommand(“属性名”, “属性値”, %[]);という形になります。その他は[char]の場合と同様なので説明は省略します。

効果音オブジェクト

[se]タグのコマンドはSEオブジェクト(world_object.env.ses[バッファ番号])を経由して呼び出します。

// @se buf=0 play=se01 と同じ動作をさせる例
world_object.env.ses[0].doCommand("play", "se01", %[]);
world_object.env.updateAll();

world_object.ses[バッファ番号].doCommand(“属性名”, “属性値”, %[]);という形になります。その他は[char]の場合と同様なので説明は省略します。

inno setupでデータを分ける方法

inno setupを使うと簡単にインストーラが作れます。詳しい説明は以下のページを参照してください。
吉里吉里/KAGゲームのインストーラの作り方(Windows 7対応)
今回の記事はこのページの説明を前提としています。

Flags: external

「おわりに」の部分に

同人レベルだったら、できればゲームファイルは纏めずにそのままCD-ROM上に配置して おけた方が、「最後の手段で手でコピーする」というのが使えてハッピーだと 思うが、まぁうん…そのくらいはいいか。

という記述がありますがinno setupでもファイルを纏めずにインストーラと別々にできます。KAICHOさんが知らなかったのか説明を省いたのか分かりませんが、特に理由がない限り別々にした方がいいです。

setup.exeのサイズが大きければ大きいほどインストーラの起動時間が長くなります。ひどい例だとsetup.exeをダブルクリックしてから一分待たないとインストール画面が出てこないこともあるようです。理由はsetup.exeにセキュリティソフトのウィルススキャンが入ったりするためです。他にもwindows側でも何かやっていた気がしますが詳細は忘れました。誰か知ってたら教えてください・・・・・・。

setup.exeとゲームデータを分ける方法はこのページに日本語で書いてあります。

前提の記事では[Files]が以下のようになっています。

[Files]
Source: "D:\同人ゲーム\我輩ゲーム\我輩ゲーム.eXe"; DestDir: "{app}";
Source: "D:\同人ゲーム\我輩ゲーム\data.xp3"; DestDir: "{app}";
Source: "D:\同人ゲーム\我輩ゲーム\plugin\*"; DestDir: "{app}\plugin";
Source: "D:\同人ゲーム\我輩ゲーム\savedata\*"; DestDir: "{app}\savedata";
Source: "D:\同人ゲーム\我輩ゲーム\readme.txt"; DestDir: "{app}";

これを例えば以下のようにします。Flags: external; を付けるのと、ファイルの場所を{src}を使ってsetup.exeからの相対パスで指定するのがポイントです。

[Files]
Source: "{src}\data\我輩ゲーム.eXe"; DestDir: "{app}"; Flags: external;
Source: "{src}\data\data.xp3"; DestDir: "{app}"; Flags: external;
Source: "{src}\data\我輩ゲーム\plugin\*"; DestDir: "{app}\plugin"; Flags: external;
Source: "{src}\data\我輩ゲーム\savedata\*"; DestDir: "{app}\savedata"; Flags: external;
Source: "{src}\data\我輩ゲーム\readme.txt"; DestDir: "{app}"; Flags: external;

この例の場合は、setup.exeと同じフォルダにdataフォルダを作り、その中に我輩ゲーム.eXeなどを入れておけばいいです。インストール時にはそれらのファイルがインストール先フォルダにコピーされます。

この記事で言いたいことはここまでです。以下はお好みでどうぞ。

AppId

[Setup]でAppIdを指定した方がいいかもしれません。アプリケーションごとの固有のIDを指定します。デフォルトではAppNameと同じになっています。ゲーム名だけでは他と被る可能性が0ではありません。どこかに表示されたりはしないので適当に被らなそうな物を指定しましょう。ホームページがあればそのURLを使うのがいいです。
例えば以下のようにすると良いと思います。http://www.biscrat.com/の部分は自分のサイトのURLを使ってください。
AppId=http://www.biscrat.com/我輩ゲーム/

AllowRootDirectory

デフォルトの状態ではC:\やD:\にはインストールできないようになっています。[Setup]にAllowRootDirectory=yesという行を書いておくとできるようになります。

AllowNoIcons

[Setup]でAllowNoIcons=yesとすると、インストーラの中で「プログラムグループを作成しない」というチェックボックスが出てくるようになります。このチェックボックスにチェックを入れるとスタートメニューにショートカットが作られません。つまり、[Icons]のなかで{group}から始まるショートカットが無視されます。

デスクトップのショートカット

少し手間がかかりますが、デスクトップのショートカットの有無も選べるようにできます。

まず以下を追加します。これでインストーラの中で「デスクトップにショートカットを作成」というチェックボックスが出てくるようになります。

[Tasks]
Name: DesktopShortcut; Description: デスクトップにショートカットを作成;

さらに、[Tasks]の中のデスクトップにショートカットを作る行にはTasks: DesktopShortcut;を付けます。前提の記事の例では、以下のようになっている行です。

Name: "{commondesktop}\我輩ゲーム"; Filename: "{app}\我輩ゲーム.eXe";

これを以下に変更します。

Name: "{commondesktop}\我輩ゲーム"; Filename: "{app}\我輩ゲーム.eXe"; Tasks: DesktopShortcut; 

UninstallDelete

アンインストール時にはインストール時にコピーしたファイルのみが削除されます。よってゲーム起動後に新規作成されたセーブデータや吉里吉里設定ツールが作成するcfuファイルなどが削除されません。アンインストール時にそれらも削除するには[UninstallDelete]で削除するファイルを登録しなければなりません。

以下はセーブデータの保存先を %APPDATA%我輩ゲーム とした場合の例です。

[UninstallDelete]
Name: {commonappdata}\我輩ゲーム\krkr.console.log; Type: files;
Name: {commonappdata}\我輩ゲーム\krenvprf.kep; Type: files;
Name: {commonappdata}\我輩ゲーム\savecheck; Type: files;
Name: {commonappdata}\我輩ゲーム\*.bmp; Type: files;
Name: {commonappdata}\我輩ゲーム\*.ksd; Type: files;
Name: {commonappdata}\我輩ゲーム\*.kdt; Type: files;     
Name: {commonappdata}\我輩ゲーム\我輩ゲーム.cfu; Type: files;
Name: {commonappdata}\我輩ゲーム; Type: dirifempty;
Name: {userappdata}\我輩ゲーム\krkr.console.log; Type: files;
Name: {userappdata}\我輩ゲーム\krenvprf.kep; Type: files;
Name: {userappdata}\我輩ゲーム\savecheck; Type: files;
Name: {userappdata}\我輩ゲーム\*.bmp; Type: files;
Name: {userappdata}\我輩ゲーム\*.ksd; Type: files;
Name: {userappdata}\我輩ゲーム\*.kdt; Type: files;               
Name: {userappdata}\我輩ゲーム\我輩ゲーム.cfu; Type: files;
Name: {userappdata}\我輩ゲーム; Type: dirifempty;
Name: {app}\我輩ゲーム.cfu; Type: files; 

これでも削除されないファイルを見つけたら教えてください。

KAGEX拡張例(自動検索パスの追加)

KAGではカスタマイズ用にOverride.tjsとAfterinit.tjsが用意されています。

KAGEXではこれに加えてStorages.tjsがあります。これは独自の検索パスを追加するためのスクリプトです。初期状態では存在しないので作成してください。

以下の例ではseフォルダとscenario/openingフォルダを検索パスに追加しています。

// Storages.tjs
Storages.addAutoPath("se/"); // seフォルダを追加
Storages.addAutoPath("scenario/opening/"); // scenario/openingフォルダを追加

KAGEXの初期状態で使えるフォルダ名はbgimage, bgm, evimage, face, fgimage, image, init, main, others, rule, scenario, sound, sysscn, system, thum, uipsd, video, voiceになります。それ以外のフォルダを使ったり、フォルダの中にフォルダを作りたいときはStorages.tjsで追加します。

KAGEX拡張例(onSoundPropertyChanged)

・前回まで
KAGEX拡張例(音量設定)
KAGEX拡張例(ミュート設定)
KAGEX拡張例(システム効果音)

BGMの音量、またはミュートの状態が変更された際は、onSoundPropertyChangedというフックが呼ばれます。kag.addHookで呼び出す関数を追加できます。大体の動作は以下を見てください。

// 音量などが変更された際に呼ばれる関数を登録
kag.addHook("onSoundPropertyChanged", function(tag, prop, value) {
    switch (tag) {
    case "bgm":
        if (prop === "enable") {
            // BGMのミュートが変更された(value => true or false)
        } else if (prop === "globalVolume") {
            // BGMの音量が変更された(value => 0~100000)
        }
        break;
    case "se":
        if (prop === "enable") {
            // 効果音のミュートが変更された(value => true or false)
        } else if (prop === "globalVolume") {
            // 効果音の音量が変更された(value => 0~100000)
        }
        break;
    case "sysse":
        if (prop === "enable") {
            // システム効果音のミュートが変更された(value => true or false)
        } else if (prop === "globalVolume") {
            // システム効果音の音量が変更された(value => 0~100000)
        }
        break;
    case "movie":
        if (prop === "enable") {
            // 動画のミュートが変更された(value => true or false)
        } else if (prop === "globalVolume") {
            // 動画の音量が変更された(value => 0~100000)
        }
        break;
    case "voice":
        if (prop === "enable") {
            // キャラ共通のミュートが変更された(value => true or false)
        } else if (prop === "globalVolume") {
            // キャラ共通の音量が変更された(value => 0~100000)
        } else if (prop === "しおり") {
            // キャラごとの音量(しおり)が変更された(value => 0~100000)
        }
        break;
    case "bgv":
        if (prop === "enable") {
            // BGV(bvoice)のミュートが変更された(value => true or false)
        } else if (prop === "globalVolume") {
            // BGV(bvoice)の音量が変更された(value => 0~100000)
        }
        break;
    case "bgv2":
        if (prop === "enable") {
            // BGV(hvoice)のミュートが変更された(value => true or false)
        } else if (prop === "globalVolume") {
            // BGV(hvoice)の音量が変更された(value => 0~100000)
        }
        break;
    case "voiceon":
        if (prop === "しおり") {
            // キャラごとのミュート(しおり)が変更された(value => true or false)
        }
        break;
    }
});

tagには”bgm”, “se”など何の値が変更されたかが渡されます。

propが”enable”ならミュートの状態、”globalVolume”なら音量が変更されたと言うことです。prop==”enable”ならvalueは通常の状態ならtrue, ミュートされた状態ならfalseになります。prop==”globalVolume”ならvalueは変更後の音量ですが、0~100000の数値になるので注意してください。value/1000のように1000で割れば0~100に変換できます。

tag==”voice”の時は少し特殊です。propが”enable”,”globalVolume”の他にキャラ名になることがあります。このときはそのキャラの音量が変更されたということです。

キャラごとのミュートはtag==”voiceon”で渡されます。propがキャラ名になります。

全体の音量(wavevolume)やミュート(waveenable)が変更されたときはonSoundPropertyChangedが呼ばれないようになっています。それも必要なときは少し改造する必要があります。
MainWindow.tjsでwavevolumeとwaveenableが定義されている部分を書き換えます。setterの最後にcallHook(~)の行を追加しただけです。これでtag==”wave”でprop==”enable”またはprop==”globalVolume”として変更が通知されるようになります。

/**
 * グローバル WaveSound 音量の設定
 * 100 段階設定
 */
property wavevolume {
    getter()  {
        return scflags.waveVolume !== void ? +scflags.waveVolume : global.WaveSoundBuffer.globalVolume / 1000;
    }
    setter(v) {
        v = +v;
        if      (v < 0)   v = 0;
        else if (v > 100) v = 100;
        scflags.waveVolume = v;
        global.WaveSoundBuffer.globalVolume = scflags.waveEnable ? v * 1000 : 0;
        callHook("onSoundPropertyChanged", "wave", "globalVolume", v * 1000);
    }
}

/**
 * グローバル WaveSound の有効値の設定
 * true / false
 */
property waveenable {
    getter() {
        return scflags.waveEnable !== void ? +scflags.waveEnable : true;
    }
    setter(v) {
        scflags.waveEnable = +v;
        wavevolume = scflags.waveVolume;
        callHook("onSoundPropertyChanged", "wave", "enable", !!v);
    }
}

KAGEX拡張例(システム効果音)

・前回まで
KAGEX拡張例(音量設定)
KAGEX拡張例(ミュート設定)

kag.sameSysSEVolume=falseの状態ではゲーム中の効果音とシステム効果音の音量を別々に設定できます。Config.tjsの効果音バッファの数を設定している部分で設定するのが良いと思います。

// ◆ 利用可能な効果音バッファの数
// 利用可能な効果音バッファの最大値を指定します。つまり、ここで指定した数の
// 分だけ効果音を同時に再生できます。効果音を使用しない場合は 0 を指定して
// かまいません。
;numSEBuffers = 3;
;numSysSEBuffers = 2;
;sameSysSEVolume = false;

numSysSEBuffersとsameSysSEVolumeの設定を追加しました。numSysSEBuffersはシステム効果音のバッファの数です。sameSysSEVolume = falseで音量を別にしています。

デフォルトのsameSysSEVolume = trueの状態でも、音量が共通になるだけでシステム効果音が使えないわけではありません。

システム効果音のバッファは通常の効果音の後ろに追加される形になります。今回の例だとバッファ番号0~2が通常の効果音バッファ、バッファ番号3~4がシステム効果音のバッファとなります。

バッファ番号を指定する際にシステム効果音の番号を指定すればシステム効果音として再生されます。

@linemode mode=none
@nowait
@link clickse=seテスト clicksebuf=4
テスト
@endlink
@endnowait
@s

4番のバッファなのでクリックするたびにシステム効果音として再生されます。

また、システム効果音はワールド拡張では効果音として使用されません。例えば[seテスト]とするとseテスト.oggが適当な空いているバッファで再生されますが、システム効果音のバッファが使われることはありません。[seテスト buf=4]のように直接指定しても使えません。システム効果音を再生したいときはtjsを使ってください。

; 4番のバッファでseテスト.oggを再生
@eval exp="kag.se[4].play(%[ storage:'seテスト' ])"

KAGEX拡張例(ミュート設定)

・前回まで
KAGEX拡張例(音量設定)

KAGEXでは0~100の音量に加えて、オン/オフの設定もあります。

kag.waveenable ゲーム全体のミュート
kag.bgmenable BGMミュート
kag.seenable 効果音ミュート
kag.sysseenable システム効果音ミュート
kag.sameSysSEVolume=falseの時のみ
kag.movieAudioEnable ムービーミュート
kag.independentMovieAudioProperty=trueの時のみ
kag.voiceenable キャラ共通のボイスミュート
kag.bgvenable キャラ共通のBGV(bvoice)ミュート
kag.bgv2enable キャラ共通のBGV(hvoice)ミュート
kag.setVoiceOn(名前, 設定) キャラごとのミュートを設定する関数
kag.getVoiceOn(名前) キャラごとのミュートを得る関数

・全てtrueまたはfalseを設定します。デフォルトではtrueです。falseにすると対象の音がミュートされます。

以下は前回のスライダの例にミュート用のチェックボックスを追加した例です。

; スライダとチェックボックスで音量を設定する使用例
@iscript
// しおりのキャラ音量のプロパティ
property voiceVolumeShiori {
  setter(value) { kag.setVoiceVolume("しおり", value); }
  getter() { return kag.getVoiceVolume("しおり", true); }
}
// しおりのキャラミュートのプロパティ
property voiceEnableShiori {
	setter(value) { kag.setVoiceOn("しおり", value); }
	getter() { return kag.getVoiceOn("しおり"); }
}
@endscript

@linemode mode=none
@backlay
@nowait

; 操作対象を message1/back に設定
@current layer=message1 page=back

; メッセージレイヤの大きさを調整
@position left=0 top=0 width=800 height=600 visible


; BGM音量スライダを追加
@locate x=0 y=0
BGM
@locate x=120 y=0
@slider width=200 height=30 min=0 max=100 value=kag.bgmvolume jumpmode
@locate x=330 y=0
@checkbox onchange=kag.bgmenable name=kag.bgmenable

; 効果音音量スライダを追加
@locate x=0 y=80
効果音
@locate x=120 y=80
@slider width=200 height=30 min=0 max=100 value=kag.sevolume jumpmode
@locate x=330 y=80
@checkbox onchange=kag.seenable name=kag.seenable

; ボイス音量スライダを追加
@locate x=0 y=160
ボイス
@locate x=120 y=160
@slider width=200 height=30 min=0 max=100 value=kag.voicevolume jumpmode
@locate x=330 y=160
@checkbox onchange=kag.voiceenable name=kag.voiceenable

; キャラ音量(しおり)スライダを追加
@locate x=0 y=240
しおり
@locate x=120 y=240
@slider width=200 height=30 min=0 max=100 value=voiceVolumeShiori jumpmode
@locate x=330 y=240
@checkbox onchange=voiceEnableShiori name=voiceEnableShiori

; 操作対象を戻す
@current layer=message0 page=fore

@endnowait

; トランジションで表示
@trans method=crossfade time=1000
@wt
@s

KAGEX拡張例(音量設定)

KAGEXのサウンドはBGM、ゲーム効果音、システム効果音、ボイス、BGVの5種類に大別できます。
その音量はプロパティまたは関数で設定できます。

kag.wavevolume ゲーム全体のマスター音量
kag.bgmvolume BGM音量
kag.sevolume 効果音音量
kag.syssevolume システム効果音音量
kag.sameSysSEVolume=falseの時のみ
kag.movieAudioVolume ムービー音量
kag.independentMovieAudioProperty=trueの時のみ
kag.voicevolume キャラ共通のボイス音量
kag.bgvvolume キャラ共通のBGV(bvoice)音量
kag.bgv2volume キャラ共通のBGV(hvoice)音量
kag.setVoiceVolume(名前, 音量) キャラごとの音量を設定する関数
kag.getVoiceVolume(名前, true) キャラごとの音量を得る関数

・音量はすべて0~100の数値になります。デフォルトでは100です。

・システム効果音はkag.sameSysSEVolumeがtrueの時のみ使えます。デフォルトではfalseです。今回は解説しません。

・動画の音量はデフォルトではBGMの音量と同じになります。kag.independentMovieAudioPropertyをtrueにすると動画の音量を別に設定できるようになります。

BGVには実はbvoiceとhvoiceの2種類があります。hvoiceの使い方はbvoiceと全く同じで、属性名がbvoiceからhvoiceになるだけです。音量調整がbgvvolumeとbgv2volumeで別々にできます。実際に使うことは滅多にありません。

・キャラごとの音量はボイス、BGVの両方に影響します。kag.voicevolumeは全キャラのボイスのみ、kag.bgvvolumeは全キャラのbvoiceのみに影響します。

以下は実際に使ってみた例です。使った見た以上の意味はありません。

; 音量設定の簡単な使用例
@linemode mode=vn

; 現在のマスター音量を表示
現在の音量は[emb exp="kag.wavevolume"]%です。

; ゲーム全体の音量を100に設定
@eval exp="kag.wavevolume = 100"

; BGMの音量を80に設定
@eval exp="kag.bgmvolume = 80"

; ボイス全体音量を20に設定
@eval exp="kag.voicevolume = 20"

; キャラ音量を50に設定
@eval exp="kag.setVoiceVolume('しおり', 50)"

; キャラ音量を表示
現在のしおりの音量は[emb exp="kag.getVoiceVolume('しおり', true)"]%です

以下は音量を調整するスライダを配置する例です。こちらはよく使うかもしれません。

; スライダで音量を設定する使用例
@iscript
// しおりのキャラ音量のプロパティ
property voiceVolumeShiori {
	setter(value) { kag.setVoiceVolume("しおり", value); }
	getter() { return kag.getVoiceVolume("しおり", true); }
}
@endscript

@linemode mode=none
@backlay
@nowait

; 操作対象を message1/back に設定
@current layer=message1 page=back

; メッセージレイヤの大きさを調整
@position left=0 top=0 width=800 height=600 visible


; BGM音量スライダを追加
@locate x=0 y=0
BGM
@locate x=120 y=0
@slider width=200 height=30 min=0 max=100 value=kag.bgmvolume jumpmode

; 効果音音量スライダを追加
@locate x=0 y=80
効果音
@locate x=120 y=80
@slider width=200 height=30 min=0 max=100 value=kag.sevolume jumpmode

; ボイス音量スライダを追加
@locate x=0 y=160
ボイス
@locate x=120 y=160
@slider width=200 height=30 min=0 max=100 value=kag.voicevolume jumpmode

; キャラ音量(しおり)スライダを追加
@locate x=0 y=240
しおり
@locate x=120 y=240
@slider width=200 height=30 min=0 max=100 value=voiceVolumeShiori jumpmode

; 操作対象を戻す
@current layer=message0 page=fore

@endnowait

; トランジションで表示
@trans method=crossfade time=1000
@wt
@s

KAGEX講座(36) – BGV再生(bvoice)

KAGEXにはBGV再生機能がついています。キャラクタのbvoiceコマンドでファイル名を指定すると再生されます。

@linemode mode=vn

@しおり bvoice=cvl_shiori__0001
BGVとしてcvl_shiori_h_0001が再生されます。

次のページに進んでも再生されたままです。

@しおり voice=cv_shiori_0001
【しおり】
「通常のボイスとしてcv_shiori_0001が再生されます。
再生されている間BGVは停止します」

通常のボイスが止まると再びBGVが再生されます。

@しおり bvoice=""
BGVを停止しました。

通常のボイス再生についてはKAGEX講座(30)を参照してください。

bvoiceコマンドにファイル名を指定するとそのキャラのBGVとして再生されます。停止したいときはbvoice=””となります。また、BGVはデフォルトでループ再生されます。再生時にloop=falseを付ければループしません。

上の例のように通常のボイスと同時には再生されません。ボイスが流れている間はBGVは自動的に停止され、ボイスの再生が終わったら自動的に再開されます。