0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

アニメーションの再生開始位置を変えたのに反映されない。犯人は「別の設定を先にONにしないといけない」でした(Godot)

0
Posted at

個人開発で3Dのゲームを作っています。コードはほとんど自分では書いていなくて、AIと一緒に作っています。

キャラクターのジャンプモーションで、こんな症状が起きました。

設定を変えたのに、画面が1ミリも変わらない。

エラーも警告も出ません。設定した値は保存されています。なのに再生される絵が変わらない。今日はこの「静かに無視される設定」を見つけるまでの話です。


そもそも、なぜ再生位置をずらす必要があったか

キャラクターのモーション素材は Mixamo(無料でモーションデータを配っているサイト)から持ってきています。1本の素材に「しゃがむ → 踏み切る → 空中 → 着地 → 立ち戻る」が全部つながって入っています。

これを頭から再生すると、ジャンプボタンを押した瞬間に「しゃがむ」から始まってしまうので、見た目としては「踏み込む前に飛んでいる」ように見えます。

そこで、「素材の何秒目から再生を始めるか」を指定する必要が出てきます。Godot(無料の3Dゲームエンジン)には、これ用の設定があります。

# AnimationNodeAnimation(AnimationTreeの中で1つのモーションを表すノード)
animation_node.start_offset = 0.4  # 0.4秒目から再生を始める、はずだった

start_offset は名前の通り「開始位置のオフセット」です。数値を大きくすれば、その分だけ頭を飛ばして再生されるはずでした。


症状:数値を変えても、絵が変わらない

start_offset を 0.4 にしても 0.8 にしても、再生される絵はまったく同じでした。

最初に疑ったのは自分のコード側でした。「値の代入に失敗しているのでは」「別の場所で上書きされているのでは」と、代入している行の周りを何度も見直しました。エラーは出ていないので、ここで時間を溶かしました。


原因:もう1つの設定が「ONになっていないと丸ごと無視する」仕様だった

調べていくと、AnimationNodeAnimation には use_custom_timeline という、もう1つの設定があることが分かりました。

Godotの公式ドキュメントで start_offset の説明を読むと、こう書いてあります(要約すると)。

start_offsetuse_custom_timeline が有効な場合にのみ使われる。

つまり、こういう関係でした。

use_custom_timeline start_offset の扱い
false(既定値) 完全に無視される。エラーも警告も出ない
true 指定した通りに再生開始位置がずれる

既定値が false なので、何も知らずに start_offset だけ設定すると、静かに無視されます。 設定した値そのものは保存されているので、コードを読んでも「効いていない」ことには気づけません。

これが「エラーも出ないのに絵が変わらない」の正体でした。


この手のバグへの対処:「設定した」で終わらせず、「効いたか」をテストで測る

use_custom_timeline を有効にすれば直る話ではあるのですが、同じ構造のバグは他の設定でも起こりえます(Godotに限らず、既定値がOFFで別の条件が要る設定は他のツールにもよくあります)。

なので、直したあとに「本当に効いているか」を自動で確かめる仕組みを足しました。

# 再生を1フレーム進めて、実際の再生位置(秒)を読み取って比較する
func _test_trimmed() -> bool:
    var actual_pos: float = animation_player.current_animation_position
    var expected_pos: float = 0.4
    return abs(actual_pos - expected_pos) < 0.05

考え方としては、設定した値を信じるのではなく、実際に再生させて出てきた数値を見るというだけです。地味ですが、この確認を挟んでから初めて「直った」と言えるようになりました。


もう1つ気をつけたこと:「使わない部分を消す」と「見た目まで消える」は別

再生位置を直したあと、別の問題も出ました。素材の「使わない部分」を切り詰めたら、今度は踏み込みの動き自体が消えてしまったんです。

原因は単純で、「この区間は今回使わない」と「この区間の動きは要らない」を混同していたことでした。着地の直前でモーションを区切ったつもりが、実際には「体が沈み込んで着地の勢いを受け止める」動きの部分ごと削っていました。

見た目のどの部分が何を表現しているかを確認せずに、時間だけで機械的に切ると、こういう事故が起きます。「切り出す」のつもりが「捨てる」になっていないか、切ったあとに見た目を確認する一手間が要りました。


まとめ

  • start_offset のような「値を設定すれば効くはず」の項目でも、別の設定が有効になっていないと丸ごと無視されることがある(今回は use_custom_timeline
  • こういうバグはエラーも警告も出ないので、値そのものを見直しても気づけない。公式ドキュメントでその項目が依存している別の設定を確認する
  • 直したら「設定した」で終わらず、実際の再生位置を読み取って数値で確認する_test_trimmed のような小さいテストで十分)
  • モーションの一部を切り詰めるときは、その区間が担っている見た目(今回は着地の沈み込み)まで消していないかを確認する

「設定を変えたのに何も起きない」ときは、その項目が何かの前提条件付きで動く仕様になっていないか、ドキュメントを疑ってみるとよさそうです。


普段は ShibaHub という無料の計算ツールを集めたサイトや、補助金ナビ を作っています。屋号は sesebox です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?