今回は、フィールドに敵を用意してプレイヤーを追いかけてくるような処理を実装したいと思います。
【Godot3D】プレイヤーを敵が追いかけてくるようにする
敵モデルは、プレイヤーにSophiaを使用しているので同様にGDquestが配布している「bee_bot」を使いたいと思います。
キャラクターのダウンロードは上記のGithubから可能です。ダウンロード及びインポートに関しては過去の記事にて紹介しているので、参考にしてください。
敵モデルシーンの継承
ファイルシステムに追加したら「gdquest_bee_bot」→「bee_bot_skin.tscn」を右クリックして「新しい継承シーン」を選択しましょう。
適当な名前でシーンを保存したら、BeebotSkinを右クリックして継承をクリアをクリックします。
これは、BeebotSkinをCharacterBody3Dノードへ変更したいがためですね。ということで、再びBeebotSkinを右クリックして型の変更を選択して「CharacterBody3D」ノードに変えます。
ちなみに、BeebotSkinの横に警告マークが出ていますが・・・。
クリックするとこんな感じのメッセージが表示されるかと思います。
この警告は、Godotエディタで表示される「ルートノードにTransformを設定してはいけない」といったニュアンスの内容になります。
Godotではシーンを他のシーンにインスタンスとして配置するケースが多いため、ルートノードは変形されないのが前提となります。
ですから、BeebotSkinを選択してインスペクターからtransformの値を全てリセットしてやることでこの警告マークは消えます。
当たり判定の設定
Sophia(プレイヤー)の時も実装しましたが、敵にも当たり判定を用意しておきましょう。
BeebotSkinを右クリックして子ノードの追加からCollisionShape3Dをアタッチします。
インスペクターからShapeをCapsuleShape3Dに変更してお好みでサイズを調整しましょう。
敵がプレイヤーを追いかけるスクリプト
予めBeebotSkinにはスクリプトがアタッチされていますが、新たにスクリプトを作りますので右クリックからスクリプトをデタッチしておきます。
続いてBeebotSkinを右クリックして、今度はスクリプトをアタッチします。
extends CharacterBody3D
@export var speed: float = 2.0
@export var rotation_speed: float = 5.0 # 回転速度
@onready var player = $"../SophiaSkin"
func _physics_process(delta):
var direction = (player.global_transform.origin - global_transform.origin)
direction.y = 0 # 高さ方向を無視して水平方向にのみ動く
var distance = direction.length()
if distance > 1.0: # プレイヤーが近すぎなければ追いかける
var move_dir = direction.normalized()
velocity = move_dir * speed
move_and_slide()
# 向きを補間しながらプレイヤー方向に回転(Y軸のみ)
var target_rotation = Vector3(0, atan2(move_dir.x, move_dir.z), 0)
rotation.y = lerp_angle(rotation.y, target_rotation.y, rotation_speed * delta)
else:
velocity = Vector3.ZERO
move_and_slide()
player変数にてノードを取得していますが、階層や取得したいノード名は恐らく異なると思いますので、適宜変更するようにしてください。
if distance > 1.0:により、プレイヤーに接近しすぎたら停止するようになっています。この辺の数値もお好みで調整してもらえればと思います。
rotation.yの補間には lerp_angle()を使って滑らかに向きを変えています。
スクリプトを保存したら、敵モデルをプレイヤーがいるステージ上の好きな位置に配置します。
ゲームを実行すると、こんな感じで敵がプレイヤーを追いかけるようになるかと思います。