ゲームエンジンGodot4.0で3Dスマホゲームを作りたいと思いますが、その前にお勉強しています。
2023/3/1にstable版がリリースされました。
Godot_v4.0-stable_win64.exe.zipを使用しています。
目的
敵の砦を倒した後にただ消えるだけでは寂しいので、砦が倒れるアニメーションを追加します。
敵の砦が消えるのと同時に、アニメーション用のシーンを生成するようにします。
ベースプロジェクト
下記で作成したプロジェクトをベースに機能追加をします。
【Godot 4.0】スマホ3Dゲームを作るための勉強 その29 ゲームの背景に空のテクスチャを貼ります
https://qiita.com/FootInGlow/items/f7661fdeadb2dbcbdbdf
github(Godotのプロジェクトマネージャーからインポートして利用できます)
https://github.com/footinglow/Godot4/tree/main/02_study/S29Background
※別途ダウンロードが必要です。
res://assets/texture/godot-material-dpa-1.0.1/Readme.txt及び
res://assets/texture/AllSkyFree1.0/Readme.txtを参照
敵の砦のアニメーション用シーンを作成する
敵の砦のアニメーションシーンを新規作成する
シーンメニューの「新規シーン」を実行します。「3Dシーン」ボタンを押下するとNode3Dが追加されます。名称を「EnemyDefeatedAnimation」に変更します。
保存します。
保存ダイアログの右上の「フォルダーを作成」ボタンを押下します。
「Decorations」(飾り)フォルダを作成します。
Decorationsフォルダに「enemy_defeated_animation.tscn」という名前で保存します。
保存されました。
敵の砦のデザインシーンを追加する
シーン内のルートノード「EnemyDefeatedAnimation」を右クリックして、「Instantiate Child Scene」を実行します。
「Design/design_enemy_fort.tscn」を開きます。
子ノードに「DesignEnemyFort」が追加されました。
DesignEnemyFortを選択して、インスペクタのNode3D/Transform/Positionのyを0.5にします。
res://Characters/enemy.tscnのDesignEnemyFortと同じ位置に設定しました。
(改めてみると少し埋まっているのに気が付きました。正しくは0.75mですが、今まで0.5mで説明してきたので0.5mとします)
AnimationPlayerを追加・設定する
シーン内のルートノード「EnemyDefeatedAnimation」を右クリックして、子ノードを追加からAnimationPlayerを追加します。
倒した敵の砦は沈み込みながら、倒れるようにします。
沈み込むのはpositionのyをマイナスに移動します。倒れるのは、Rotationのzを操作してZ軸周りを90°回転するようにします。
画面下部の「アニメーション」メニューをクリックして、「新規」を実行します。
「Defeated」という名前で追加します。
次に「+トラックを追加」をクリックして「プロパティトラック」を選択します。
回転対象としてDesignEnemyFortを選択します。
rotationを選択します。
同様に、「+トラックを追加」をクリックして「プロパティトラック」を選択して、移動対象としてDesignEnemyFortのPositinを選択します。
アニメーションの長さ(秒)は2秒にします。
rotationの右、0秒のあたりを右クリックして「キーを挿入」します。2秒のあたりにもキーを挿入します。
同様に、positionの0秒と2秒のあたりにもキーを挿入します。
追加したキーをクリックすると、右側のインスペクタで値を設定することができますので、それぞれ下記の表のように設定します。
項目名 | Time | 設定値 |
---|---|---|
rotation | 0.0 | (x,y,z)=( 0°, 0°, 0° ) |
rotation | 2.0 | (x,y,z)=( 0°, 0°, 90° ) |
position | 0.0 | (x,y,z)=( 0m, 0.5m, 0m ) |
position | 2.0 | (x,y,z)=( 0m, -0.5m, 0m ) |
再生ボタンを押下して、アニメーションを実行して確認します。
アニメーション開始時(Time=0.0秒)
EnemyDefeatedAnimationのAPIを作成
ルートノードの「EnemyDefeatedAnimation」を右クリックして「スクリプトをアタッチ」を実行します。
res://Decorations/enemy_defeated_animation.gdとして作成します。
アニメーションを実行するAPIを実装します。
extends Node3D
func animation_play(name):
$AnimationPlayer.play(name)
次にアニメーションが完了したときにEmitされるシグナルを利用して自身を削除するようにします。
AnimationPlayerを選択した状態で、インスペクタの横のノード/シグナルをクリックします。
AnimationPlayer/animation_finished(anim_name:StringName)を右クリックして、「接続」を実行します。
「EnemyDefeatedAnimation」を選択します。
「func _on_animation_player_animation_finished(anim_name):」が追加されました。
アニメーション終了時に呼び出されるので自身を削除するように修正します。
extends Node3D
func animation_play(name):
$AnimationPlayer.play(name)
func _on_animation_player_animation_finished(anim_name):
queue_free()
倒された敵の砦が消えるときに、EnemyDefeatedAnimationシーンを生成する。
敵の砦のスクリプトの中でhpが0未満になった場合に消える処理の前に、EnemyDefeatedAnimationシーンの生成処理を追加します。
res://Characters/Enemy.gdを開きます。
メンバ変数にPackedSceneを宣言して@exportします。
@export var m_scn_enemyDefeatedAnim : PackedScene
スクリプトを保存します。
res://Characters/enemy.tscnを開いて、ルートノードのEnemyを選択してインスペクタを確認すると、「Enemy.gd/M Scn Enemy Defeated Anim」が追加されています。
<空>の右の「v」アイコンをクリックしてクイックロードを実行します。
「Decorations/enemy_defeated_animation.tscn」を開きます。
「EnemyDefeatedAnimation」シーンを設定しました。
次に、敵の砦シーンを消す前に、EnemyDefeatedAnimationシーンを生成します。
res://Characters/Enemy.gdの「_physics_process」メソッドを下記のように修正します。
func _physics_process(delta):
if m_hp < 0.0:
var ins = m_scn_enemyDefeatedAnim.instantiate()
ins.transform.origin = transform.origin
add_sibling(ins)
ins.animation_play("Defeated")
queue_free()
-
var ins = m_scn_enemyDefeatedAnim.instantiate()
先ほど登録したEnemyDefeatedAnimationシーンを生成します。 -
ins.transform.origin = transform.origin
表示位置をEnemyと同じ位置に設定します。 -
add_sibling(ins)
生成したシーンをEnemyと同じ階層に追加します。 -
ins.animation_play("Defeated")
Defeatedアニメーションの実行を開始します。 -
queue_free()
倒されたEnemyシーンを削除依頼します。
実行
以上です。