7. 選択肢・条件分岐・ウェイト
この節では、里々が「書き方」として用意していた3つ、選択肢(_)、条件分岐(>、when、iflist)、ウェイト(自動挿入)を扱います。
選択肢
里々の _ラベル は、湊にはありません。さくらスクリプトの \q[ラベル,ID] を直接書きます。 里々も内部でこの形に変換していたので、書く内容は同じです。
イベント名を ID にする
SSPの \q[ラベル,ID] は、ID が On で始まる場合、そのイベントを直接実行します。選ばれたときに動くトークを、OnXxx という名前で定義します。
OnBoot => {
湊: どっちにしますか?
\q[りんご,OnApple]
\q[みかん,OnOrange]
}
OnApple => {
湊: りんごですね。
}
OnOrange => {
湊: みかんですね。
}
\0どっちにしますか?\n\q[りんご,OnApple]\n\q[みかん,OnOrange]\e
\0りんごですね。\e
\0みかんですね。\e
\q[…] の行は、直前のセリフに \n(改行)付きで連結されます。選択肢が縦に並ぶのは、この改行のおかげです。
\q[ラベル,OnID,値0,値1] のように、ID のあとに値を続けると、それが選ばれたイベントの reference["0"]、reference["1"] に入ります。
OnAnswer => {
湊: ${reference["0"]}が選ばれました。
}
\0yesが選ばれました。\e
里々のように「ラベル=ジャンプ先のトーク名」にする
里々では、_はい と書くだけで *はい に飛びました。同じ動きにするには、ID を On で始めず、トーク名にします。すると SSPは、OnChoiceSelect イベントを reference["0"] に ID を入れて送ります。これを受けて call reference.0 で呼び出します。
OnBoot => {
湊: どっち?
\q[はい,はい]
\q[いいえ,いいえ]
}
OnChoiceSelect => {
call reference.0
}
はい => {
湊: はいが選ばれました。
}
いいえ => {
湊: いいえが選ばれました。
}
\0どっち?\n\q[はい,はい]\n\q[いいえ,いいえ]\e
\0はいが選ばれました。\e
(204)
call reference.0は、reference["0"]の文字列をトーク名として呼びます。里々と同じく、同名のトークが複数あればランダムに1つ選ばれます。- 存在しない名前のときは、何も出力されず 204 になります。エラーにはなりません。
- 選択肢が増えるたびに
OnChoiceSelectの中身を書き換える必要はありません。
里々の選択肢関連の変数
里々の (選択ID) (選択ラベル) (選択番号) に当たる変数は、湊にはありません。SSPが送る Reference から取り出します。
| 里々 | 湊 |
|---|---|
(選択ID) | OnChoiceSelect の reference["0"](On で始まらない ID のとき) |
(選択ラベル) | OnChoiceSelectEx の reference["0"](SSPのみ)。ID は reference["1"] |
(選択番号) | なし |
選択肢を条件で出す
里々では \q[(見たもの1フラグ),選択肢…] のように書きました。湊では、\q の行を if で囲みます。
OnBoot => {
湊: どれにしますか?
\q[りんご,OnApple]
if (save.見た) {
\n\q[みかん,OnOrange]
}
}
OnSet => {
global save.見た = true
}
\0どれにしますか?\n\q[りんご,OnApple]\e
(204)
\0どれにしますか?\n\q[りんご,OnApple]\n\q[みかん,OnOrange]\e
if の中の \q の行は、直前のセリフとは連結されないので、改行の \n を自分で書く必要があります。
条件分岐
| 里々 | 湊 |
|---|---|
>ジャンプ先【タブ】条件式 | if (条件) { call … return }(4. ジャンプ) |
(when,条件,真の値,偽の値) | choose(条件, 真の値, 偽の値) |
(iflist,左辺,右辺1,結果1,…,偽の結果) | if … else if … else、または match |
ssu.dll の if unless | if (条件)、if (!条件)、または choose() |
ssu.dll の switch nswitch | match |
条件式の == >= &&(全角も可) | == >= &&(半角のみ) |
里々の iflist は、範囲で分岐するときによく使われました。湊では、if の連鎖を関数にまとめると読みやすくなります。
func 時間帯(h) {
if (h < 6) {
return "深夜"
} else if (h < 12) {
return "朝"
} else if (h < 18) {
return "昼"
}
return "夜"
}
OnBoot => {
湊: ${時間帯(5)} ${時間帯(11)} ${時間帯(12)} ${時間帯(23)}
湊: ${choose(true, "はい", "いいえ")}
}
\0深夜 朝 昼 夜\nはい\e
if の条件は、真偽値ではなく どんな値でも書けます。その場合の真偽の判定は、5. 型と暗黙の型変換の規則に従います。
match
値による分岐は match です。数値と文字列は、内容が同じなら一致とみなされます("3" は 3 に一致します)。
OnBoot => {
let x = "3"
match x {
3 => {
湊: 数値3にマッチ
}
_ => {
湊: その他
}
}
}
\0数値3にマッチ\e
_ はどれにも一致しなかったときの分岐です。1 | 2 => のように | で複数の値をまとめられます。
ウェイト
里々が自動で入れていたウェイトは、湊にはありません。 句読点で間を空ける処理(replace.txt や $自動挿入ウェイトタイプ)も、スコープ切り替え時の自動ウェイトもありません。何も書かないと、間のない速い喋りになります。
手で書く
さくらスクリプトの \w5(50ミリ秒)や \_w[500] をそのまま書きます。
文字列リテラルの中の \ は1つだけ
セリフの中でも、文字列の中でも、\w5 は1つのバックスラッシュで書きます。\\w5 と2つ書くと、ウェイトになりません。文字列の中の \\ は2文字のまま残るため、さくらスクリプトとしては「バックスラッシュという文字を表示する」の意味になるからです。
OnBoot => {
let ok = "あ\w5い"
let ng = "あ\\w5い"
湊: ${ok}|${ng}
}
\0あ\w5い|あ\\w5い\e
句読点に自動でウェイトを付ける
里々の replace.txt(句読点の置き換え)に当たる処理は、replace() を使った関数で作れます。
func wait(s) {
return replace(replace(s, "、", "、\w3"), "。", "。\w9")
}
OnBoot => {
湊: ${wait("今日は、いい天気ですね。")}
}
\0今日は、\w3いい天気ですね。\w9\e
セリフごとに ${wait("…")} と書く必要があります。全体に一括で適用する仕組みはありません。
すべての出力に一括で適用したい場合は、SSPの OnTranslate イベントを使う方法があります(3. イベント)。ただし、この方法は、選択肢のラベルや \![…] の引数の中の句読点にもウェイトを入れてしまうので、慎重に使ってください。
スコープの切り替えと改行
里々では、: で始まる行ごとに話者が交互に切り替わり、切り替え時に $スコープ切り替え時(\n[half] など)が自動で挿入されました。
湊では、話者を毎回書き、切り替え時の挿入もありません。
OnBoot => {
湊: 一行目\n[half]
助手: 二行目
湊: 三行目
助手: 四行目
}
\0一行目\n[half]\1二行目\0\n三行目\1\n四行目\e
- 話者が変わるときは、
\0\1のタグが入るだけです。\n[half]のような間隔は、自分で書きます。 - 一度話した話者に戻るときだけ、直後に
\nが自動で入ります。 上の例の\0\n三行目と\1\n四行目がそうです(config.tomlのauto_newline = falseで止められます)。
サーフェス
[数字] を話者の前に付けると、その話者の発話の直前に \s[数字] が入ります。セリフの途中に入れたいときは、\s[数字] を直接書きます。
OnBoot => {
[5]湊: 5番
湊: \s[3]3番
助手: 助手
}
\0\s[5]5番\n\s[3]3番\1助手\e
里々の (5) のような括弧でのサーフェス切り替えは使えません。$デフォルトサーフェス や $会話時サーフェス戻し、$サーフェス加算値 のような自動処理もありません。トークの先頭で、必要なサーフェスを毎回書いてください。
次は8. SAORI呼び出しに進んでください。