[ITG] Lua講座(第3回) Rateに応じてMVの再生速度を変える – Magical Love Words

f:id:kai_yuki:20200322231406p:plain

やりたいこと

rateオプションで曲速度を変更した場合にMVの再生速度も合わせて変更したい

動画


ダウンロード


Lua

説明

等速でクリアできない曲の速度を落として練習したり、トレーニングのために曲の速度を上げてプレイするなど、rateオプションによって曲の速度を変更する場合、MVは等速で再生されてしまうため曲とどんどんずれていってしまいます。
self:rate()によってMVの再生速度を制御することができるため、プレイ時のrateオプションの値を取得し制御することで、rateオプションを使用しても変わらずMVを鑑賞できるようにしたいと思います。


PlayerIsUsingModifier ( int playerNumber, string modifier )は、プレイヤーがmodifierに記述されていたオプションを使用していれば1、そうでなければ0を返すbool関数です。
Rateオプションの設定値は内部で”〇.〇xmusic”という文字列で保持されているため、0.5から2.0まで0.1刻みでチェックし、該当すればその値をMVrate変数に代入するという実装をしています。
BGAのレイヤではself:rate(MVRate)でMVの再生速度を変えています。


modifierとしてどういった値を取れるかについては、参考URLにあるLua API for OpenITG / NotITG(https://sm.heysora.net/doc/)にも記述が無いですが、オプション画面で選べる選択肢については対応するmodifierが概ねある=luaを通じて制御できるのではないかと思います。
(2020/3/13追記:modifierの一覧表を教えてもらいました。ハイスピやrate等の数値指定でないmodifierは網羅されているようです:https://sm.heysora.net/itg.txt)

ただし、modifierの中には曲中で変更できないものもあるようです(ShuffleやBlender等については再読み込みが必要)
また、曲中で見た目のハイスピを変更する(PIUでよく出現するギミック)方法については参考URLのparaphrohn’s diary(https://paraphrohn.hateblo.jp/)にて詳しく解説されています。


参考① rateオプションがOpenITGで選べない場合の対処法

OpenITG\Themes\home\metrics.iniの[ScreenOptionsMaster] [ScreenPlayerOption]に、以下を追記することでrateオプションを追加することができます。

参考② SCREENMAN:GetTopScreen():GetChild('SongOptions')と文字列操作を使用した実装

上記の実装ではrateの変更が0.1刻みであるということを仮定した実装であるため、例えば0.05刻みに変更できるようなテーマでは想定通りに動きません。
これを解決する実装を以下に示します。


1つ目のレイヤで、rateオプションの数値を取得する関数getRateMod()を定義しています。
変数にlocalを付けていますが、特に関数の定義においては他のレイヤから関数内の変数そのものを参照することが無いことがわかっているので、変数被りを避けるためlocal変数にしておくのが無難です。


local so = SCREENMAN:GetTopScreen():GetChild('SongOptions')
local s = ''
if not so then return 1.0 else s = so:GetText() end
if not s then return 1.0 end


SongOptionのActorを取得しsoに代入、文字列にしたものをsに代入しています。
何らかの理由で値が取れなかった場合は1.0を返すエラー処理をしています。


local fbegin = string.find(s,'.',1,true)
local fend = string.find(s,'xMusic')
if fbegin and fend then
return tonumber(string.sub(s,fbegin-1,fend-1))


文字列sに対する文字列操作で”〇.◇xMusic”の.とxMusicの位置を取得して、.の1文字前からxMusicの1文字前までの文字列を取得,さらにtonumberで数値化することにより〇.◇の部分を取得する、という流れです。
string.findの引数はそれぞれ取得元文字列、検索対象パターン、検索開始位置(〇文字目)、検索対象パターンを単なる文字列とみなすかどうか、の4つです。
fbeginの取得で3つ目と4つ目の引数を指定しているのは’.’の検索のみだと正規表現とみなされるためです。
また、実装上、rate10.0などの.の前が2桁になっているパターンは考慮していません。(そもそもrate10倍ってまともに動くんでしょうか)


オプション取得回りの実装の話はparaphさんのブログの最近の記事でも触れられていたので、見比べてみるのもよいと思います。
https://paraphrohn.hateblo.jp/entry/2020/03/09/221821

参考URL

Lua API for OpenITG / NotITG(英語)
https://sm.heysora.net/doc/
ITGのLuaを書くのにまず参照するページ。OpenITGで使用できる各種命令が記載されている。

paraphrohn’s diary
https://paraphrohn.hateblo.jp/
日本語でLuaの解説が書かれた貴重なページです。Luaの基本から譜面のワープ、ハイスピ変更ギミックなど様々な実装についての解説があります。