mieki256's diary



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

#4 [godot] Godot Engineでプレイヤーの弾を撃つ

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

今回はプレイヤーの弾を撃ってみる。

プレイヤーの弾のシーンを作成。 :

プレイヤーの弾のシーン res://asets/PlayerBullet.tscn を作成する。

ルートノードに Area、その下に表示モデルを担当する Spatial、MeshInstance と、アタリ範囲を担当する CollisionShape を追加する。

3d_tuto06_create_player_bullet_ss01.png

Area
  ├─ Spatial
  │     ├─ MeshInstance
  │     └─ MeshInstance
  └─ CollisionShape

Areaノードは、表示モデルとアタリ範囲を持って、かつ、物理法則に従わない動きをする物体に使うノードらしい。

MeshInstance の Mesh に割り当てた Material で、Emission(発光)を有効にしておく。これで、画面に表示されたときに光ってる感じになって少しは目立つはず。

3d_tuto06_create_player_bullet_ss02.png


ルートノードを PlayerBullet にリネーム。

3d_tuto06_create_player_bullet_ss03.png


res://assets/ の下に PlayerBullet.tscn として保存。

3d_tuto06_create_player_bullet_ss04.png

スクリプトファイルを追加。 :

スクリプトファイル、res://scripts/PlayerBullet.gd を追加。PlayerBullet を選択して、右上のスクリプトアタッチアイコンをクリック。

3d_tuto06_create_player_bullet_ss05.png

タイマーノードを追加。 :

本来なら、弾が画面外に出たら自分を消去する処理を作りたいけれど、画面外かどうかを判別する方法が分からない…。

とりあえずの簡易処理として、弾が出現して一定時間が経過したら自分自身を消去するようにしてみる。そのために Timerノードを追加。

3d_tuto06_create_player_bullet_ss06.png


Timerノードのプロパティを設定。
  • Wait Time を 2 に。
  • One Shot にチェックを入れて有効化。
  • Autostart にチェックを入れて有効化。

3d_tuto06_create_player_bullet_ss07.png


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

3d_tuto06_create_player_bullet_ss08.png


PlayerBullet を選択して「接続」。

3d_tuto06_create_player_bullet_ss09.png


スクリプトファイル PlayerBullet.gd に、_on_Timer_timeout() が追加された。自分自身を消去するメソッド、queue_free() を追記する。

3d_tuto06_create_player_bullet_ss10.png

これで、PlayerBullet が画面に出現すると Timer が自動実行されて、指定時間が来たら自分を消去、という処理になる。

弾の移動処理を追加。 :

プレイヤーの弾のスクリプトファイル res://scripts/PlayerBullet.gd に、弾の移動処理を追加する。以下を記述。

_PlayerBullet.gd
extends Area

var velocity = Vector3()
var speed = 90

func _ready():
    velocity = Vector3(0, 0, -1)

#func _process(delta):
#   pass

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

func _on_Timer_timeout():
    queue_free()

translate(velocity * speed * delta) で、現在座標を (velocity * speed * delta) 分変化させている。

プレイヤーの弾を登録するノードを用意。 :

Mainシーンに、発生させたプレイヤーの弾を登録していくためのノード、PlayerBullets を用意する。

Mainシーンを開いて Spatial ノードを追加。

3d_tuto06_create_player_bullet_ss11.png


PlayerBullets にリネーム。

3d_tuto06_create_player_bullet_ss12.png

プレイヤーから弾を発生させる。 :

プレイヤーキャラから弾を発生させる。今回はショットボタンを押さなくても自動・一定間隔で弾を次々に発射するようにしてみる。

プレイヤーのシーン、Player.tscn を開いて、Timerノードを追加。ShotTimer にリネーム。このタイマーを使って弾の発生処理をさせる。

3d_tuto06_create_player_bullet_ss13.png


ShotTimerのプロパティを設定。
  • Wait Time は 0.065 に。高橋名人が1秒間に16連射していたらしいので、それに近い値を指定してみたつもり。
  • Autostart にチェックを入れて有効化。

3d_tuto06_create_player_bullet_ss14.png


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

3d_tuto06_create_player_bullet_ss15.png


Player を選択して「接続」。

3d_tuto06_create_player_bullet_ss16.png


Playerのスクリプトファイル、res://scripts/Player.gd に、_on_ShotTimer_timeout() というメソッドが追加された。ShotTimer で設定した時間間隔で、このメソッドが呼び出される。

Player.gd に以下を記述。

_Player.gd
extends KinematicBody

export (PackedScene) var PlayerBullet

const SPEED = 32
var velocity = Vector3()

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

#func _process(delta):
#   pass

func _physics_process(delta):
    # move
    velocity = Vector3()
    if Input.is_action_pressed("ui_right"):
        velocity.x = 1
    elif Input.is_action_pressed("ui_left"):
        velocity.x = -1
    if Input.is_action_pressed("ui_down"):
        velocity.z = 1
    elif Input.is_action_pressed("ui_up"):
        velocity.z = -1
    
    # Do not multiply by delta when using move_and_slide()
    velocity = velocity.normalized() * SPEED
    move_and_slide(velocity)

func _on_ShotTimer_timeout():
    var bullet = PlayerBullet.instance()
    bullet.translation = Vector3(translation.x, translation.y, translation.z - 1.0)
    get_tree().root.get_node("Main/PlayerBullets").add_child(bullet)

  • 最初のほうで、export (PackedScene) var PlayerBullet を書いて、PlayerBulletシーンを入れておく変数 PlayerBullet を用意する。
  • _on_ShotTimer_timeout() の中でプレイヤーの弾の発生処理をする。PlayerBullet のインスタンスを生成、座標を Player のちょっと前に設定してから、Mainシーンの PlayerBulletsノードに登録している。

Playerシーンのプロパティ Player Bullet に、PlayerBulletシーンを設定する。Playerノードを選択して、Player Bullet の横の「空」をクリックして「読込み」。

3d_tuto06_create_player_bullet_ss17.png


res://assets/PlayerBullet.tscn を選択して「開く」。これで、Player Bullet にプレイヤーの弾のシーンを設定できた。

3d_tuto06_create_player_bullet_ss18.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