【Godot Engine】画面遷移時のアニメーションのやり方を検討してみる
前回
読み込みスクリプト
前回とほぼ同じですが、今回の用途から少しだけ修正。読み込み完了の状態を保持しておくように finished を追加しました。
SceneLoader.gd
extends Node # 読込進捗通知シグナル signal _scene_loading(percent) # 読込完了シグナル signal _loaded_scene(scene) # 読込失敗シグナル signal _scene_load_error # ローディング実行時間 const limit_msec = 100 # ローダー var loader # 読み込み完了 var finished = false # 対象シーンパス設定 func set_target_scene(path): # ローダー作成 loader = ResourceLoader.load_interactive(path) if loader == null: return FAILED return OK # ローディング処理 func process(delta): if loader == null || finished: return var time = OS.get_ticks_msec() while OS.get_ticks_msec() < time + limit_msec: var ret = loader.poll() if ret == OK: # 読み込み実行 continue elif ret == ERR_FILE_EOF: # 読み込み完了 finished = true emit_signal('_loaded_scene', loader.get_resource()) return else: # 読み込み失敗 emit_signal('_scene_load_error') loader = null return # 進捗通知 var p = float(loader.get_stage() + 1) / float(loader.get_stage_count()) emit_signal('_scene_loading', p)
自動ロード
今回は使用しません。登録済みの SceneLoader.gd は解除します。
サンプルシーン作成
今回も3つのシーンを作成します。
- FromScene.tscn ・・・ 遷移元画面
- ToScene.tscn ・・・ 遷移先画面
- Transition.tscn ・・・ ローディング、アニメーション用Node。FromScene と ToScene に組み込んで使用する。
画面遷移用 Node
ルートは ColorRect でカラーは黒を設定します。子にアニメーション用の Tween を追加します。画面表示時用と画面終了用の2つを用意しておきます。
簡単にフェードイン・フェードアウトアニメーションのみです。
Transition.gd
extends ColorRect var scene_loader = preload('res://SceneLoader.gd').new() var next_scene var exit_anim_completed # シーン変更 func change_scene(target_path): scene_loader.set_target_scene(target_path) _start_exit_anim() func _enter_tree(): scene_loader.connect("_scene_loading", self, "_on_scene_loading") scene_loader.connect("_loaded_scene", self, "_on_loaded_scene") scene_loader.connect("_scene_load_error", self, "_on_scene_load_error") # 画面表示アニメーション開始 _start_enter_anim() func _exit_tree(): scene_loader.disconnect("_scene_loading", self, "_on_scene_loading") scene_loader.disconnect("_loaded_scene", self, "_on_loaded_scene") scene_loader.disconnect("_scene_load_error", self, "_on_scene_load_error") func _process(delta): scene_loader.process(delta) # Enterアニメーション func _start_enter_anim(): # Nodeを表示する visible = true # アニメーション $EnterAnim.interpolate_property( self, "color", Color(1, 1, 1, 1), Color(1, 1, 1, 0), 1, Tween.TRANS_LINEAR, Tween.EASE_IN) $EnterAnim.start() # Exitアニメーション func _start_exit_anim(): # Nodeを表示する visible = true # アニメーション $ExitAnim.interpolate_property( self, "color", Color(1, 1, 1, 0), Color(1, 1, 1, 1), 1, Tween.TRANS_LINEAR, Tween.EASE_IN) $ExitAnim.start() # 画面遷移 func _next_scene(): # Scene読み込み済み、アニメーション終了済みであれば画面遷移する if next_scene and exit_anim_completed: visible = false get_tree().change_scene_to(next_scene) # Enterアニメーション完了処理 func _on_EnterAnim_tween_completed(object, key): # Nodeを非表示 visible = false # Exitアニメーション完了処理 func _on_ExitAnim_tween_completed(object, key): exit_anim_completed = true # 画面遷移 _next_scene() # ローディング中 func _on_scene_loading(p): # ローディング中の画面表示を更新 print("Loading... %d" % [int(p * 100)]) # ロード完了 func _on_loaded_scene(scene): next_scene = scene # 画面遷移 _next_scene() # ロード失敗 func _on_scene_load_error(error_type): # エラーの場合の表示 print('error:' + str(error_type))
遷移元画面
ボタン一つと、一番ツリーの下に Transition を追加します。
FromScene.gd
extends Sprite
func _on_Button_pressed():
$Transition.change_scene('res://ToScene.tscn')
遷移先画面
こちらも同様
ToScene.gd
extends Sprite
func _on_Button_pressed():
$Transition.change_scene('res://FromScene.tscn')
動作確認