mieki256's diary



2020/11/14() [n年前の日記]

#6 [godot] Godot Engineで敵から弾を撃たせる

Godot Engine 3.2.3 x64 を使って3D表示の簡単なシューティングゲームっぽいものを作る。

今回は敵から弾を撃たせてみる。

敵弾シーンを作成。 :

敵弾用のシーン EnemyBullet.tscn を作成していく。「シーン」 → 「新規シーン」を選択。

3d_tuto08_create_enemy_bullet_ss01.png


ルートノードとしてAreaノードを登録して、その下に以下のノードを追加。

3d_tuto08_create_enemy_bullet_ss02.png


ルートノードをEnemyBulletにリネーム。Timer を KillTimer にリネーム。

3d_tuto08_create_enemy_bullet_ss03.png

EnemyBullet (Area)
  │
  ├─ MeshInstance
  │
  ├─ CollisonShape
  │
  └─ KillTimer (Timer)


MeshInstance の Meshプロパティで、新規 SphereMesh を選んで、球の形をしたモデルを設定。

3d_tuto08_create_enemy_bullet_ss04.png


Material で Emission を有効にして発光するようにした。

3d_tuto08_create_enemy_bullet_ss05.png


アタリ範囲(CollisionShapeが担当)は、Shape で SphereShape を指定。球の形でアタリ範囲を指定できる。

3d_tuto08_create_enemy_bullet_ss06.png


res://assets/EnemyBullet.tscn としてシーンを保存した。

スクリプトを追加。 :

EnemyBulletノードを選択してスクリプトファイルをアタッチ。res://scripts/EnemyBullet.gd として保存した。

タイマーを設定。 :

本来なら、敵弾が画面外に出たかどうかを判別して、出ていたら自分(= 敵弾)を消去する、という処理をしたいけれど…。今回も、とりあえずの簡易処理として、一定時間が経過したら自分を消去、という処理にして誤魔化しておく。

KillTimer を設定。
  • Wait Time を 3 に。
  • Autostart を有効化。

3d_tuto08_create_enemy_bullet_ss07.png


timeoutシグナルにメソッドを接続する。ノードタブをクリック → timeout を選択して右クリック → 「接続」。

3d_tuto08_create_enemy_bullet_ss08.png


EnemyBullet を選択して「接続」すれば、EnemyBullet.gd に _on_KillTimer_timeout() というメソッドが追加される。自分を消去する queue_free() を追記。

3d_tuto08_create_enemy_bullet_ss09.png

移動処理を書く。 :

res://scripts/EnemyBullet.gd に移動処理を書く。内容は以下。

_EnemyBullet.gd
extends Area

var velocity = Vector3()
var direction = 0
var speed = 3

func _ready():
    pass # Replace with function body.

#func _process(delta):
#   pass

func _physics_process(delta):
    translate(velocity * speed * 60 * delta)

func set_dir_and_speed(angle, spd):
    direction = angle
    speed = spd
    var x = cos(deg2rad(angle))
    var z = sin(deg2rad(angle))
    velocity = Vector3(x, 0, z)
    
func _on_KillTimer_timeout():
    queue_free()

set_dir_and_speed(角度、速度)を呼ぶことで、敵弾が飛んでいく方向と移動速度について初期設定ができるようにした。

敵に敵弾の発生処理を追加。 :

敵に、敵弾の発生処理を追加していく。EnemyZako.tscn を開いて、以下を行う。

  • Timerノードを追加して、ShotTimer にリネーム。
  • スクリプトファイル EnemyZako.gd の最初のあたりに、export (PackedScene) var enemybullet を追記。


変数 enemybullet に、GUI操作で、敵弾シーン EnemyBullet.tscn を指定しておく。Enemybulletプロパティの横の「空」をクリックして「読込み」。

3d_tuto08_create_enemy_bullet_ss10.png


res://assets/EnemyBullet.tscn を選択して「開く」。

3d_tuto08_create_enemy_bullet_ss11.png


敵弾を発生させるタイマー、ShotTimer を設定。
  • Wait Time を 1 に。1秒毎に敵弾を発生させる。
  • Autostart を有効化。

3d_tuto08_create_enemy_bullet_ss12.png


timeoutシグナルにメソッドを接続。EnemyZako を選んで「接続」。

3d_tuto08_create_enemy_bullet_ss13.png


res://scripts/EnemyZako.gd の最後に、_on_ShotTimer_timeout() メソッドが追記される。この中に敵弾の発生処理を書いていけばいい。

3d_tuto08_create_enemy_bullet_ss14.png


EnemyZako.gd に、敵弾の発射処理を追加。以下の内容になる。ここでは敵弾を扇状に発射する処理を追加してる。

_EnemyZako.gd
extends Area

export (PackedScene) var enemybullet

var base_pos = Vector3()
var angle = 0
export var move_w = 22
export var move_h = 12
var bullets

func _ready():
    base_pos = translation
    angle = 0
    bullets = get_tree().root.get_node("Main/EnemyBullets")

#func _process(delta):
#   pass

func _physics_process(delta):
    move(delta)
    
func move(delta):
    angle += delta
    translation.x = base_pos.x + move_w * cos(deg2rad(angle * 90))
    translation.z = base_pos.z + move_h * sin(deg2rad(angle * 70))
    
func _on_ShotTimer_timeout():
    var angle_add = 12
    var angle = 90 - angle_add * 3
    var spd = 0.2
    for i in range(7):
        _shot(translation, angle, spd)
        _shot(translation, angle, spd * 0.8)
        angle += angle_add
    
func _shot(pos, angle, spd):
    var bullet = enemybullet.instance()
    bullet.translation = pos
    bullet.set_dir_and_speed(angle, spd)
    bullets.add_child(bullet)

Mainシーンに敵弾用のノードを追加。 :

Mainシーンに、敵弾を登録していくためのノードを追加する。Main.tscn を開いて、Mainノードの下に Spatialノードを追加。

3d_tuto08_create_enemy_bullet_ss15.png


EnemyBullets にリネーム。

3d_tuto08_create_enemy_bullet_ss16.png

動作確認。 :

Mainシーンを開いた状態でF6キーを押して動作確認。

3d_tuto08_create_enemy_bullet_ss17.png


1秒毎に、扇状に敵弾が発射される状態になった。しかし、敵弾が大き過ぎた…。調整しないといけない。

敵弾のサイズその他を調整。 :

考えてみたら、敵弾如きに奇麗で滑らかな球の3Dモデルは要らないなと思えてきた。サイズを調整するついでにポリゴン数をグンと減らして、ガクガクした感じの球のモデル(Mesh)にしてみた。どうせ小さく表示されるのだから分からないだろう…。
  • Radius で、球のモデルの半径を指定。
  • Height で、球のモデルの高さを指定。
  • Radial Segments と Rings で、球のモデルにどのくらいポリゴン数を使うかを指定。多ければ滑らかな球になるし、少なくすればガクガクした球になる。

3d_tuto08_create_enemy_bullet_ss18.png


また、敵弾が自分で消滅するまでの時間が短すぎた気がする。まだ画面の中に表示されているのにどんどん消えていくので不自然極まりない。時間を長目に調整。EnemyBullet の KillTimer の Wait Time を5に変更。

3d_tuto08_create_enemy_bullet_ss19.png


動作確認。Mainシーンを開いてF6キーを押す。



それっぽく表示された。

次回は各オブジェクトのアタリ属性を設定していきたい。

以上です。

過去ログ表示

Prev - 2020/11 - Next
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project