💻

人はIntel(R) Celeron(R) CPU 3865U @ 1.80GHzで3Dゲームを開発できるのか? Part02

に公開

はじめに

この記事は前回の続きです。とはいってもここから読んでも問題ないと思われます。

人はIntel(R) Celeron(R) CPU 3865U @ 1.80GHzで3Dゲームを開発できるのか? -Zenn版-

以下本文

初めましての人は初めまして、普段ゲーム制作やら3D数学の勉強やらやっているえうなひゃともうします。

現在Youtubeの企画で以下のスペックのPCを使ってGodot Engineを使ったゲーム開発を行なっております。

  • CPU:Intel(R) Celeron(R) CPU 3865U @ 1.80GHz
  • MEMORY:4GB
  • GRAPHICS:Intel HD Graphics 610

ちなみにOSはWindowsではなくLinuxのディストリビューションの一つDebianでデスクトップ環境はXfceにしております。

なぜこのようにしたのかの経緯は上記の記事にございます。

私のYoutubeチャンネル

私のX

ここに書くこと

今回は以下のアーカイブで行ったことをブログにしてまとたものです。

人はIntel(R) Celeron(R) CPU 3865U @ 1.80GHzで3Dゲームを開発できるのか? その4 #linux #xfce #godotengine #vtuber

まず何をしたのか整理していきます。

  • 敵キャラを2種類実装
  • プレイヤーのモデルをフリーのあいつに変更
  • プレイヤーがミスした時を実装(まだ未完成)

敵キャラについて

まず敵キャラについてですがCharacterBodyではなくAreaで実装することに決めました。

というのもAreaが当たり判定をもっているノードの中で最もリソースを食わないからです。

どういうことかというとCharacterBodyはその性質上、どうしても色々な情報を感知して反応を行う必要があり、(例えば、今床に着地しているのかを判定するis_on_floor()メソッドや壁にぶつかっているのかを判定するis_on_wall()メソッドが存在する。)その分、計算を取られてしまうというジンクスがあるからです。

2Dゲームであればなんとかなるかもしれませんがこれは3Dゲームです。非常に重たくなるのは明らかです。

以下に公式ドキュメントへのリンクを貼るので確認すると役割の違いから検出する必要のあるもの違いがわかると思います。

両者を比較すると例えばArea3Dはとれるアイテムや当たると4ぬトラップに、CharacterBody3Dはプレイヤーや敵キャラに適用するのが適切に思えます。

しかし、敵キャラに計算のリソースを食わせるのはCeleronに優しくなく、今回のゲーム開発のゴールから遠ざかってしまうため、Area3Dで敵キャラを実装することにいたしました。

他にも当たり判定に気を使っております。以下は配信の時に撮影したスクリーンショットです。

ステージの当たり判定

敵の当たり判定

プレイヤーの当たり判定

右側のCollistionのあたりに注目してほしいのですが当たり判定はレイヤーで管理されており、

アクティブになっていないところは無視するという仕様があります。

これをうまく管理していけばCPUに余計な計算をしないように最適化が可能です。

また、Godotにはレイヤーに名前をつけることができるため、それも採用しました。

当たり判定のレイヤー

以下はこれらを踏まえた敵のスクリプトです。

extends Area3D
@onready var animation_player = $AnimationPlayer
## 派生として前に進むタイプの敵をなんとか製作したい。
enum EnemyType {
	WAIT,
	WALKING,
	FLYING
}

@export var enemy_type : EnemyType = 0

func _ready() -> void:
	match enemy_type:
		EnemyType.WAIT:
			animation_player.play("Dance")
		EnemyType.FLYING:
			animation_player.play("Flying")


func _on_body_entered(body: Node3D) -> void:
	# プレイヤーは4ぬ
	animation_player.play("Bite_Front")
	body.die()


func _on_weak_area_body_entered(body: Node3D) -> void:
	# 前提としてプレイヤーしか侵入不可
    # なぜならレイヤーの数値で管理しているから
	body.bounce()
	animation_player.play("Death")


func _on_animation_player_animation_finished(anim_name: StringName) -> void:
	match anim_name:
		"Death":
			await get_tree().create_timer(0.5).timeout
			hide()
			$CollisionShape3D.disabled = true
			$WeakArea/CollisionShape3D.disabled = true


ソースコードを見ればわかる通り、敵のエリアを2つ作成し、一つはプレイヤーに当たったらミス判定するように、もう一つはプレイヤーが頭に乗っかったら敵が消えるように設定されております。

次はこれにRayCast3Dを追加することで前のものを認知して振り返ったりする処理とか入れていきたいと考えております。

今後の課題

  • 敵キャラが左右に動いたりとかして壁にぶつかったり一定時間経ったら振り返るAIの実装
  • アクションゲームに欠かせない動く床などのギミックを搭載した何か、一気に実装したいので実際にクラッシュを遊んで確認しようかな
  • 敵のバリエーションを増やす。ダウンロードしたサイトにエネミーパックみたいなものがあったのでそれを使う方針で

最後に

普段は以下のコンテンツを配信しております。

  • この記事で述べたロースペPCでの開発配信
  • goghを使った視聴者参加型作業配信
  • Godot Engineの使い方をまとめた動画
  • Godot Engineのソースコードを閲覧する配信

よかったらチャンネル登録・高評価等をよろしくおねがいします。

以下は私のチャンネルです。

えうなひゃ

Discussion