アニメーションをGDScriptから制御する方法

Gobot

牛肉・豚肉・鶏肉・ジビエ情報:アニメーションのGDScript制御

Godot EngineのGDScriptを用いて、牛肉・豚肉・鶏肉・ジビエといった食材の3Dモデルにアニメーションを適用し、制御する方法について解説します。これらの食材をゲームやアプリケーションで魅力的に表現するためには、リギングされたモデルとGDScriptによるインタラクションが不可欠です。

3Dモデルの準備とインポート

まず、各食材の3Dモデルが必要です。これらのモデルは、Blenderなどの3Dモデリングソフトウェアで作成し、アニメーション(例えば、調理中の揺れ、カットされる様子、あるいはキャラクターが食べるアニメーションなど)をリギングとともに適用しておきます。Godot Engineは、glTF 2.0形式でのエクスポートを推奨しています。これは、マテリアル、テクスチャ、ボーン、アニメーションといった情報を保持したままインポートできるため、最も効率的です。

Godot Editorにモデルをインポートしたら、シーンツリーで確認します。通常、glTFファイルは.tscnファイルとしてインポートされ、シーンツリーにはNode3DをルートとしたMeshInstance3DSkeleton3DAnimationPlayerノードなどが含まれます。

アニメーションの再生と制御

GDScriptでアニメーションを制御する最も基本的な方法は、AnimationPlayerノードを利用することです。AnimationPlayerノードは、シーン内に存在するすべてのアニメーションクリップを管理し、再生、停止、一時停止、スクラブなどの操作を可能にします。

AnimationPlayerノードへのアクセス

GDScriptからAnimationPlayerノードにアクセスするには、$演算子を使用するのが一般的です。例えば、シーンツリーでAnimationPlayerノードの名前がAnimationPlayerであれば、スクリプト内で$AnimationPlayerとして参照できます。


@onready
var animation_player = $AnimationPlayer

func _ready():
    # アニメーションの確認や初期設定を行う
    pass

アニメーションの再生

特定のアニメーションを再生するには、animation_player.play("アニメーション名")メソッドを使用します。アニメーション名は、Godot EditorのAnimationPlayerパネルで定義されているクリップ名と一致する必要があります。


func play_cooking_animation():
    animation_player.play("cooking_stir") # 「cooking_stir」という名前のアニメーションを再生

func play_eating_animation():
    animation_player.play("eating")      # 「eating」という名前のアニメーションを再生

play()メソッドには、再生速度を指定するオプション引数(custom_speed)や、ループ再生するかどうかを指定する引数(transition_time)もあります。

アニメーションの停止と一時停止

アニメーションを停止するにはanimation_player.stop()を使用します。特定のアニメーションのみを停止したい場合は、animation_player.stop(true)のように引数trueを渡すことで、現在再生中のアニメーションのみを停止できます。

一時停止するにはanimation_player.pause()、一時停止を解除して再生を再開するにはanimation_player.play()(あるいはanimation_player.unpause())を使用します。

アニメーションの進捗状況の取得

アニメーションの現在の再生位置や進捗状況を知りたい場合は、animation_player.get_current_animation_position()animation_player.get_current_animation_length()といったメソッドが利用できます。


func _process(delta):
    var current_pos = animation_player.get_current_animation_position()
    var anim_length = animation_player.get_current_animation_length()
    if anim_length > 0:
        var progress = current_pos / anim_length
        print("Animation progress: ", progress * 100, "%")

アニメーションとゲームロジックの連携

食材のアニメーションは、ゲーム内のイベントやプレイヤーの操作と連携させることで、よりインタラクティブで没入感のある体験を提供します。

プレイヤーのインタラクションによるアニメーショントリガー

例えば、プレイヤーが食材をクリックまたはインタラクトした際に、調理アニメーションや食べるアニメーションを再生するように設定できます。


func _input(event):
    if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
        var camera = get_viewport().get_camera_3d()
        var from = camera.project_ray_origin(event.position)
        var to = from + camera.project_ray_normal(event.position) * 1000
        var space_state = get_world_3d().direct_space_state
        var query = PhysicsRayQueryParameters3D.create(from, to)
        var result = space_state.intersect_ray(query)

        if result and result.collider == self: # クリックされたのがこの食材(自身)の場合
            play_cooking_animation()

状態管理とアニメーションの切り替え

食材が「生」「調理中」「調理済み」「食べられた」といった状態を持つ場合、これらの状態遷移に応じて適切なアニメーションを再生します。match文やif/elif文を用いて、現在の状態に基づいて再生するアニメーションを切り替えることができます。


enum FoodState { RAW, COOKING, COOKED, EATEN }
var current_state = FoodState.RAW

func set_state(new_state):
    current_state = new_state
    match current_state:
        FoodState.RAW:
            play_raw_idle_animation() # 生の状態のアニメーション
        FoodState.COOKING:
            play_cooking_animation()  # 調理中アニメーション
        FoodState.COOKED:
            play_cooked_idle_animation() # 調理済みの静止アニメーション
        FoodState.EATEN:
            play_eating_animation()   # 食べられたアニメーション

アニメーションイベントの活用

AnimationPlayerには、「アニメーションイベント」という機能があります。これは、アニメーションの特定のフレームでGDScript関数を呼び出すことができる機能です。例えば、調理アニメーションの途中で効果音を鳴らしたり、調理済みの印を付けたりするのに役立ちます。

AnimationPlayerノードのインスペクターパネルで、アニメーションを選択し、「トラック」タブから「コールバック」トラックを追加します。そのトラック上でキーフレームを追加し、関連付ける関数名を指定します。そして、その関数をスクリプトに実装します。


func on_cooking_sizzle_event():
    # 調理の「ジュージュー」という効果音を再生する
    $AudioStreamPlayer3D.stream = load("res://sounds/sizzle.wav")
    $AudioStreamPlayer3D.play()

パフォーマンスへの配慮

多数の食材アニメーションを同時に再生する場合、パフォーマンスに影響を与える可能性があります。以下のような点に注意しましょう。

  • 非表示オブジェクトのアニメーション停止: 画面外や非表示になっているオブジェクトのアニメーションは、_process_physics_processでの更新を停止したり、AnimationPlayer.queue()animation_player.seek()などで直接制御したりして、CPU負荷を軽減します。
  • アニメーションの最適化: 不要なボーンやキーフレームを削除し、アニメーションを軽量化します。
  • LOD (Level of Detail): 遠距離のモデルには簡易なアニメーションを適用するか、アニメーション自体を停止させることを検討します。

まとめ

GDScriptによる牛肉・豚肉・鶏肉・ジビエといった食材アニメーションの制御は、AnimationPlayerノードを中心に、アニメーションの再生、停止、進捗管理、そしてゲームロジックとの連携といった要素を組み合わせることで実現されます。プレイヤーのインタラクションやゲームの状態に応じて、これらのアニメーションを動的に変化させることで、より豊かで魅力的なゲーム体験を創出することが可能になります。