ゲーム作りにおいて、動きは命です。
ただ置いてあるだけのコインと、くるくると回っているコイン。どちらが「ゲットしたい!」と思わせるかは明白ですよね。
でも、**「回すためだけに、コインのスクリプトを開いて、_process関数を書いて…」**というのは面倒だと思いませんか?既存のコードを汚したくないし、管理も大変になります。
そこで今回は、**「親ノードにポイっと追加するだけで、勝手に回り出す」**便利なコンポーネント(部品)を作ります。コードはコピペでOKです!
どんなことができるの?
この「Rotator(ローテーター)」ノードを、回転させたいオブジェクトの子として追加するだけです。
- 2D / 3D 両対応:スプライトも3Dモデルも回せます。
- コード記述不要:親オブジェクトのスクリプトを一切触りません。
- 設定が楽:回転スピードや軸(3Dの場合)をインスペクターで調整できます。
用途の例:
- フィールドに落ちているコインやアイテム
- UIのロード中アイコン
- プレイヤーの周りを回る防衛ビット
- ふわふわ漂う背景のデブリ
ステップ1:スクリプトの作成
まずは、新しいスクリプトを作成します。ファイル名は rotator_component.gd としましょう。
以下のコードをコピーして貼り付けてください。
class_name RotatorComponent
extends Node
## 親ノードを継続的に回転させるコンポーネント
## Node2D (2D) と Node3D (3D) の両方に対応しています。
# 回転スピード(度/秒)
# マイナスにすると逆回転します
@export var rotation_speed: float = 90.0
# 3D用の回転軸設定(2Dの場合は無視されます)
# デフォルトはY軸(縦軸)回転
@export var axis: Vector3 = Vector3.UP
func _process(delta: float) -> void:
var parent = get_parent()
if parent is Node2D:
# 2Dの場合の回転処理
parent.rotation_degrees += rotation_speed * delta
elif parent is Node3D:
# 3Dの場合の回転処理
# 指定された軸(axis)を中心に回転させます
parent.rotate(axis.normalized(), deg_to_rad(rotation_speed * delta))
コードの解説(読み飛ばしOK)
class_name RotatorComponent: これを書くことで、Godotの「ノード追加」メニューから「RotatorComponent」と検索して追加できるようになります。これが便利!@export: インスペクター(エディタ右側の設定画面)から数値をいじれるようにするための魔法の言葉です。get_parent(): 自分の親、つまり「くっついている相手」を取得します。is Node2D/is Node3D: 親が2Dなのか3Dなのかを自動判別して、適切な回し方をしています。
ステップ2:実際に使ってみよう
使い方は驚くほど簡単です。
- 回転させたいオブジェクト(例:Coinのシーンや、Spriteノード)を選択します。
- 「子ノードを追加」(+ボタン)をクリック。
- 検索バーに「Rotator」と入力し、先ほど作ったRotatorComponentを選びます。
これだけです!ゲームを再生(F5)してみてください。そのオブジェクトが回り始めているはずです。
ステップ3:カスタマイズする
追加した RotatorComponent を選択して、画面右側のインスペクターを見てみましょう。
- Rotation Speed: 回転の速さです。
90なら1秒間に90度(4秒で1周)。360なら1秒で1回転。-90のようにマイナスを入れると逆回転します。
- Axis (3Dのみ): どの軸で回るかです。
x: 0, y: 1, z: 0(Y軸) → コマのように横回転(デフォルト)x: 1, y: 0, z: 0(X軸) → 鉄棒のように縦回転x: 0, y: 0, z: 1(Z軸) → 風車のような回転
まとめ:コンポーネント指向のすすめ
このように、機能(回転すること)を独立したノードに切り出す手法を**「コンポーネント指向」**と呼びます。
この方法の最大のメリットは、「コインのスクリプト」に「回転するコード」を書かなくて済むことです。コインのスクリプトには「拾われた時の処理」だけを書けばいいので、コードがとてもスッキリします。
(ブログ執筆者へのメモ)
このコンポーネントは、Godot 4.x系で動作確認済みとして記述しています。Godot 3.xの場合は rotation_degrees などのプロパティ名は同じですが、super() などの継承周りの記述が必要ないため、このまま3系でも動く可能性が高いですが、念のためターゲットバージョンに合わせて微調整してください。
