Aviutlでオブジェクト数に応じた計算がしたい
by 桜葵月
音ゲーなどの手元動画を撮影した際、スコアが見にくいことがよくある
小さいだけならその部分だけ切り抜いて拡大すればいいのかもしれないけど、勿論引き延ばしてるだけ粗くなるし、手元と被って見えなくなることもしばしば。
「いっそのことテキストオブジェクトで作っちゃおうか...」
そう思った次第である。
しかしこれ、愚直にテキストオブジェクトで1フレームずつやってると本当に気の遠くなる作業だ。オブジェクトを分割、テキスト内容を書き換え、スコアが見えないときはゲームの判定から推測し電卓で計算...。
めちゃくちゃめんどくさい
たまに分割漏れとか計算ミスが発覚し、そこからあとの内容をまたちまちま書き直しなんてこともよくある。そういうわけでスクリプト制御でなんとかしようと模索してるのだ。
前置きはここまでにして、ここから本題。
理想として、特定のオブジェクトの数に応じてテキストの内容が変わると言うもの
最初に思いついたもの
code:lua
score = score + 100
mes(score)
超シンプル。
0(1)フレーム目に<? score=0 ?>と書いたオブジェクトを置いておく。
しかしこれ問題しかなくて、実際に動かしてみるとフレームが動くたびにscoreの値が増加していく。
というわけで「オブジェクトの最初のフレーム時だけ」という条件を付けてみる。
code:lua
if obj.frame == 1 then
score = score + 1
end
mes(score)
しかしこれもうまく行かない。実はこの処理が行われるのは編集プロジェクトのフレームレートに依存しているのではなく、Aviutl自体でなんらかの処理(マウスを動かすなど)が行われるとスクリプトの処理も動いているっぽい。
つまり、拡張編集を最大に拡大した状態で、同一フレーム内でマウスをドラッグしてるとscoreの値がドラッグした分だけ増加する。
あと、エンコードするたびに最終的なscoreの値がバラバラ。これじゃあ使いものにならん...
よくある「ボタンを押すとxの値がn増える」みたいな処理をそのままオブジェクトに引き継ごうとしたけど、それではダメっぽい...
その2 中間点を使ってみる
一旦スコア関連のことは諦め別のスクリプトを組んでいたある時、なにやら便利そうなスクリプトを見つけた
こちらのfunctionを使えば中間点の区画に応じてスコア計算ができるかも?
code:lua
<? local function get_section_index()
--~~中略~~
return math.floor(L+(time-Lt)/(getst(R)-Lt)) --整数を返すためにここだけ改変
end
local score = 0
score = 500 * get_section_index() --スコアの増加量
mes(score)
?>
↑をテキストオブジェクトに書き込んで中間点を設けてあげると、たしかに中間点の通過数に応じてスコアが変動していく。
これでやりたいことの8割は実現。やったね
その3 でもこれ比例変化しかできないじゃん
音ゲーは判定によってスコアが変動するし、音ゲー以外の場面でも増加量が固定なのってちょっと限られてるかも?
じゃあscoreをローカルじゃなくてグローバル変数にして、各判定用のテキストオブジェクトを作ればいっか...
プログラミング初心者だから何も考えずににグローバル変数に流しがちだけど、そうやってると詳しい人たちから「この書き方はよくない」と怒られそう
code:?.lua
--layer1のテキストオブジェクト
<? local function get_sec() ~略~ end
sc_good = 0
sc_good = 300* get_sec() ?>
--layer2のテキストオブジェクト
<? local function get_sec() ~略~ end
sc_perfect = 0
sc_perfect = 500* get_sec() ?>
--必要に応じて同様のオブジェクトを追加
--layerNのテキストオブジェクト
<? mes(sc_good + sc_perfect +...) ?>
各オブジェクトのsc_○○ = 0 っているの?って思うけどこれなしだとプレビューがうまく行かないことがある気がするから一応入れておく(この辺もよくわかってない)
layerNで読み込んだ後、グローバル変数の物って破棄したほうが良いのか...?教えて有識者
よくわかってないのにスクリプトを公開するなって?それはそう()
その4 外部スクリプト化して比例以外のスコアに対応する
外部スクリプト化すればトラックバーが使えるから、それを用いて多少複雑な計算式でもスコア計算を実現してみようの回
例えば、(音ゲーではないけれど)倒した敵の数や種類、コンボで点数の加算量が変動する場合を考えてみる。
code:lua
@スコア計算
--track0:スコア1,0,100,1,1
--track1:スコア2,0,100,1,1
--track2:スコア3,0,100,1,1
--track3:スコア4,0,100,1,1
local function get_sec() ~略~ end
local s,score = {},0
for i = 1,4 do
local si = obj.getvalue(i-1,0,get_sec()) end
score = s1 + s2 * s3 * s4 --スコア計算の例 obj.load("text",score)
obj.draw()
トラックバーを瞬間移動に設定すれば先ほどよりは複雑な計算も可能になる。
ただしその時その時のスコアが表示されるだけでスコア合計出ない...ってことで修正。
code:lua
@合計スコア計算
--track0:スコア1,0,100,1,1
--track1:スコア2,0,100,1,1
--track2:スコア3,0,100,1,1
--track3:スコア4,0,100,1,1
local function get_sec() ~略~ end
local s,score,sum_score = {},{},{}
for k = 1,get_sec() do
for i = 1,4 do
si = obj.getvalue(i-1,0,k) end
scorek = s1 + s2 * s3 * s4 --ここの式を適宜変更 sum_scorek = scorek + sum_scorek-1 end
obj.draw()
こんな感じでしょうか。もう少し効率的に処理できそうな気もするけどとりあえず思いついたものを投下
各中間点においてトラックバーの値を変更しなきゃいけないけど、ボタンポチポチするだけでできるからある程度は楽できるはず。
あとはobj.effect(...)で文字色を変えるなり装飾するなり大きさ整えるなりしてください
中間点ではなく、別々のオブジェクトで計算させる方法については現段階では思いついていません。何か良い方法があったら誰か教えて...
EOF。