0
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?

More than 1 year has passed since last update.

【Godot 4.0】スマホ3Dゲームを作るための勉強 その30 敵の砦を倒した時のアニメーション

Posted at

 ゲームエンジン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」に変更します。
 保存します。
 保存ダイアログの右上の「フォルダーを作成」ボタンを押下します。
スクリーンショット (419).png
「Decorations」(飾り)フォルダを作成します。
スクリーンショット (420).png
 Decorationsフォルダに「enemy_defeated_animation.tscn」という名前で保存します。
スクリーンショット (421).png
 保存されました。
スクリーンショット (422).png

敵の砦のデザインシーンを追加する

 シーン内のルートノード「EnemyDefeatedAnimation」を右クリックして、「Instantiate Child Scene」を実行します。
「Design/design_enemy_fort.tscn」を開きます。
スクリーンショット (423).png
子ノードに「DesignEnemyFort」が追加されました。
スクリーンショット (424).png

 DesignEnemyFortを選択して、インスペクタのNode3D/Transform/Positionのyを0.5にします。
 res://Characters/enemy.tscnのDesignEnemyFortと同じ位置に設定しました。
 (改めてみると少し埋まっているのに気が付きました。正しくは0.75mですが、今まで0.5mで説明してきたので0.5mとします)
スクリーンショット (447).png

AnimationPlayerを追加・設定する

 シーン内のルートノード「EnemyDefeatedAnimation」を右クリックして、子ノードを追加からAnimationPlayerを追加します。
スクリーンショット (425).png

 倒した敵の砦は沈み込みながら、倒れるようにします。
 沈み込むのはpositionのyをマイナスに移動します。倒れるのは、Rotationのzを操作してZ軸周りを90°回転するようにします。 

 画面下部の「アニメーション」メニューをクリックして、「新規」を実行します。
スクリーンショット (426).png
 「Defeated」という名前で追加します。

 次に「+トラックを追加」をクリックして「プロパティトラック」を選択します。
スクリーンショット (428).png
 回転対象としてDesignEnemyFortを選択します。
スクリーンショット (429).png
 rotationを選択します。
スクリーンショット (430).png

 同様に、「+トラックを追加」をクリックして「プロパティトラック」を選択して、移動対象としてDesignEnemyFortのPositinを選択します。
 アニメーションの長さ(秒)は2秒にします。
スクリーンショット (434).png

 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 )

 再生ボタンを押下して、アニメーションを実行して確認します。
スクリーンショット (450).png
 
 アニメーション開始時(Time=0.0秒)
スクリーンショット (448).png

 アニメーション終了時(Time=2.0)
スクリーンショット (449).png

EnemyDefeatedAnimationのAPIを作成

 ルートノードの「EnemyDefeatedAnimation」を右クリックして「スクリプトをアタッチ」を実行します。
スクリーンショット (437).png
 res://Decorations/enemy_defeated_animation.gdとして作成します。
スクリーンショット (438).png

 アニメーションを実行するAPIを実装します。

extends Node3D

func animation_play(name):
	$AnimationPlayer.play(name)

 次にアニメーションが完了したときにEmitされるシグナルを利用して自身を削除するようにします。
 AnimationPlayerを選択した状態で、インスペクタの横のノード/シグナルをクリックします。
AnimationPlayer/animation_finished(anim_name:StringName)を右クリックして、「接続」を実行します。
スクリーンショット (439).png
「EnemyDefeatedAnimation」を選択します。
 スクリーンショット (440).png
「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」アイコンをクリックしてクイックロードを実行します。
スクリーンショット (441).png
 「Decorations/enemy_defeated_animation.tscn」を開きます。
 スクリーンショット (442).png
 「EnemyDefeatedAnimation」シーンを設定しました。
スクリーンショット (443).png

 次に、敵の砦シーンを消す前に、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シーンを削除依頼します。

実行

 敵の砦が沈みつつ倒れるようになりました。
スクリーンショット (446).png

 以上です。

0
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
0
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?