1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Godot スプライトシート化で起動時間を短縮する

Last updated at Posted at 2024-04-12

要約

  • スプライトファィルを集約したら起動時間が短くなった
  • Sprite2DをAnimatedSprite2Dに置き換える事で変更作業量を軽減できる

環境:Godot4.2+ C#(.Net Framework6.0)

はじめに

 Godotで開発を始めて半年くらい経ちますが、開発環境の立ち上げに時間がかかるようになってきました。他のゲームエンジンに比べれば全然速いんですが、空白のプロジェクトの立ち上げ時間+3秒位かかっています。
 ファィル数も増えてきたので仕方のない事かな…とも思いましたが、その時集中して行っていた作業が主に画像ファィルの追加(複数の敵キャラの実装)でした。単なる直感ですがスプライト画像ファィルの構成が影響しているかも?と思い至ります。
 まだ開発序盤でありこの先さらに画像ファィルを追加する事がわかっています。徐々に遅くなる開発環境の立ち上げは精神衛生によろしくありません。

という事で開発作業を一時中断して構成変更を試みます。

構成変更前

 思いつくままゲームオブジェクトをデザインしていたので、オブジェクト1つに1枚のスプライトシートの構成になっていました。

 構成変更前のイメージとしては以下のようなファィル構成です。

before

 この時のファィル数と起動時間は以下の通りです。

項目
画像ファィル数 51 枚
起動時間平均 6.30 sec

構成変更後

 上記の散逸した画像ファィルを3枚のスプライトシートファィルに集約します。背景画像やシェーダー用、パーティクル用の画像はスプライトシート化していません。

after

 集約した後の画像ファィ数と起動時間は以下の通りです。

項目
画像ファィル数 16 枚
起動時間平均 5.80 sec

 単純計算ですが画像ファィルを35枚減らしたことで0.5秒の短縮になります。奇しくも1ファィル当たり1/60秒に近しい時間の短縮となり、結構な効果が得られた!という印象です。

構成変更に伴うコード修正

 Sprite2DのAnimation-hFrames, vFramesを用いて画像ファィルを分割し、Frameの値を更新してアニメーションしていた箇所は少々手間がかかります。

inspector

 Frame番号が連続した0~nである事を想定したハードコードを、スプライトシート全体を対象とした分割後のFrame番号に置き換える必要が出てきます。
 スプライトシートに特に工夫をせずピクセル位置だけを合わせて配置しなおしたので、Frame番号の変更は当然として連続した番号ですらなくなります。

oh-no

 考えるだけで気を失いそうな作業です。この後もスプライトシートに追加変更を行う予定なので確実にエンバグするでしょう。
 ここはSprite2DからAnimatedSprite2Dに型の変更を行う事にしました。実際のスプライトシート上のFrame番号ではなくAnimatedSprite2DのFrame番号として扱えるよう仮想化(誤魔化し)レイヤーを挟んでエンバグを抑える回避策を採用しました。

virtualize

 Sprite2DをAnimatedSprite2Dに変更してもVisible、Frame、SelfModulateといったプロパティ名は変わりません。スプライトシート上のFrame番号をAnimatedSprite2Dのdefaultアニメーションフレーム番号として置き換える事で、現時点での色々な厄介事から解放されます。

 もちろん実行時のコストは多少増えるでしょうから性能影響が懸念されます。が…それは問題が顕在化した時に考える事とします(笑)

 ※2DスプライトのSTGなので性能問題はほぼ起きないでしょう。

before.cs

	private Sprite2D _sprite;
    _sprite = GetNode(GC.Sprite2D) as Sprite2D;

    _sprite.Visible;
    _sprite.Frame = trans.fno;
    _sprite.SelfModulate = color;

after.cs

	private AnimatedSprite2D _sprite;
    _sprite = GetNode(GC.AnimatedSprite2D) as AnimatedSprite2D;

    _sprite.Visible;
    _sprite.Frame = trans.fno;
    _sprite.SelfModulate = color;

余談

 演出効果として自機の周りにチャージショットの溜め時間を円グラフで表示するシェーダーを使っていましたが、スプライトシート全体にたいしてシェーダーの効果がかかるのでスプライトシート化は諦め1ファィルで取り扱う事にしました。
 元々は徐々に円グラフを表示していましたが、スプライトシート化で一気に全体が表示されるようになりました。インスペクターで数値を変えながら観察した所、スプライトシート全体に効果が適用されたためだと理解しました。

 またパーティクル用の画像ファィルはAnimationによるスプライト切り出しがそもそも出来ないので、これも1ファィルとして残しました。

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?