mieki256's diary



2020/04/02(木) [n年前の日記]

#1 [godot] Godot Engineで弾を撃つ

Godot Engine でプレイヤーの弾を撃つ処理をどう書けばいいのか悩んでいたのだけど。公式ドキュメントのFPS関連チュートリアル記事を眺めて、なんとなく分かってきた。環境は、Windows10 x64 1909 + Godot Engine 3.2.1 x64。

_パート2 - Godot Engine latest ドキュメント

とりあえず、プレイヤーの弾を担当するシーン、PlayerBullet.tscn を作成しておいて…。

プレイヤーキャラを担当するシーン、Player.tscn に割り当てたスクリプトの中で、以下のような感じで処理。ちなみにプレイヤーは、KinematicBody から作った。
extends KinematicBody

var bullet = preload("res://assets/PlayerBullet.tscn")

# ...

var shot_counter = 0

func _ready():
    shot_counter = 0

    # ...

func _physics_process(delta):

    # ...

    # born player bullets
    shot_counter += delta
    if shot_counter >= (4 * 1.0 / 60.0):
        shot_counter = 0
        _born_player_bullet(translation)

    # ...
            
func _born_player_bullet(pos):
    var clone = bullet.instance()
    clone.translation = pos
    clone.translation.z -= 2.5
    var scene_root = get_tree().root.get_children()[0]
    scene_root.add_child(clone)

var bullet = preload("res://assets/PlayerBullet.tscn") で、事前にプレイヤー弾のシーンを読み込んでおいて、bullet.instance() でインスタンスを作成。しかるべきノードに、add_child(clone) で、子ノードとして追加。これで一応画面上にプレイヤーの弾が次々に発生してくれた。

プレイヤーの弾の移動。 :

プレイヤーの弾は、画面奥へと飛んでいってほしい。そのあたりの処理を試したり。

プレイヤーの弾は、Area で用意した。
Area
    MeshInstance
    CollisionShape

スクリプトは以下のような感じで。
extends Area

var counter = 0
export var kill_time = 2.0
export var speed = 1.5
var velocity = Vector3()

func _ready():
    counter = 0


func _physics_process(delta):
    counter += delta
    if counter >= kill_time:
        queue_free()
        return
    
    velocity = Vector3(0, 0, -speed * 60 * delta)
    translation += velocity

translation の z に値を加算、というか減算してみたら、奥方向に移動していく感じで動いてくれた。

ただ、こういう動かし方でいいのか分からんけど…。KinematicBody の場合は move_and_slide() を呼んで動かしてたけど、Area の場合は move_and_slide() を呼ぼうとしても「そんなメソッドは無い」と言われてしまって。しかし、こんな動かし方をしてもいいのだろうか…。どうなんだろう…。

そのままだと、ずっとどこまでも飛んで残り続けてしまうので、時間を測って一定時間が経ったら自分を殺す、みたいな処理も一応入れた。本当は画面外に出たかどうかチェックして消すべきだろうけど、どうやってソレを調べればいいのか…。

衝突判定で悩んだ。 :

プレイヤーの弾、及び、敵を、Area から作っていったのだけど。何かと衝突したら body_entered シグナルが発生するはず、と思って処理を書いたら無反応で悩んだり。

調べてみたら、body_entered は、xxxxBody と衝突した時にだけ発生するようで…。StaticBody とか、RigidBody とか、KinematicBody とか。

Area と Area が衝突した際は、area_entered が発生するらしい。

しかし、自分に何が当たったのかを、どうやって調べたらいいのか…。ググってみたら、どうやらグループというものが使えそうな気配。

プレイヤーの弾には「player_bullet」を、敵には「enemy」を、グループ登録しておいて…。例えば敵の側の area_entered と接続した関数内で、以下のように書けば…。
func _on_EnemyZako_area_entered(area):
    if area.is_in_group("player_bullet"):
        # Collide with player bullets
        damage_timer = 0.3
        hp -= area.attack_point
        print("Hit. My HP = " + String(hp))
        if hp <= 0:
            queue_free()  # I am dead.
area.is_in_group("グループ名") で、当たった何かがそのグループなら、てな感じの処理が書ける。

このあたり、レイヤーとマスクを使うことでも処理ができそうな気もするけれど、まだそこまで調べてなかったり。

#2 [pc] SocketAM4 M/Bが届いた

TSUKUMOに注文していたM/Bが届いた。 _GIGABYTE B450M S2H rev. 1.0。 税込7,300円、だった気がする。SocketAM4対応。AMD Ryzen CPU が載せられるはずのM/B。

箱には、Ryzen 3000番台に対応、とシールが貼ってあった。ということは、M/B の BIOS は比較的新しい…状態だったら助かるのだけど、さて。

まだ箱を開けてないけど、日本語マニュアルも同梱、と箱に書いてある…。マニュアルも何もついてこないよ、というレビュー記事を読んだ記憶があるけど、やっぱりつけるようになったのだろうか。ただ、GIGABYTEのサイトには、日本語マニュアルのPDFが無いんだよな…。どういうことだろう…。

2020/04/03追記。 :

箱を開けてみたら、日本語で書かれた紙が、底のほうに1枚入ってた。一応、M/B上のどこに何の端子があるのか、図で示してあるけれど、例えば、ケース側のLEDその他を繋ぐ F_PANEL のピン配置などは一切書かれてなかった。やはり、GIGABYTEのサイトから英語版のマニュアルPDFを入手して、必要なページを印刷するなりしておいてから作業を始めたほうが良さそうだなと…。 *1

*1: 徹底的にコスト削減したと謳ってる(?)製品なので、これはこれでOK。マニュアル冊子がついてない分お安くしましたよ、ということだろう…。

以上、1 日分です。

過去ログ表示

Prev - 2020/04 - 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