今回はオブジェクトに**「ふわふわとした浮遊感」**を与えるコンポーネントを作ります。

ゲームにおいて、ただ地面に置いてあるだけのアイテムと、空中にふわふわと浮いているアイテム。どちらが「神秘的」で「重要そう」に見えるでしょうか?

もちろん後者ですよね。

今回作る「Floater(フローター)」ノードを使えば、あらゆるオブジェクトを**サイン波(Sine Wave)**のリズムに乗せて、優雅に上下運動させることができます。

どんなことができるの?

このノードを子として追加するだけで、親オブジェクトが上下にゆっくり揺れ始めます。

  • 自然な動き: カクカクせず、滑らかに行ったり来たりします(サイン波を使用)。
  • ランダム開始: 複数のアイテムが並んでいても、全員が同じタイミングで動かないように「ズレ」を自動で作ります(これ重要!)。
  • 2D / 3D / UI 対応: スプライト、3Dモデル、そしてUIのボタンやウィンドウにも使えます。

用途の例:

  • 獲得できる宝石やパワーアップアイテム
  • 「New!」などの注目させたいUIアイコン
  • 会話ウィンドウの「▼」カーソル
  • 幽霊や浮遊する敵キャラの待機モーション

ステップ1:スクリプトの作成

新しいスクリプトを作成します。ファイル名は floater_component.gd としましょう。

以下のコードをコピーして貼り付けてください。

GDScript

class_name FloaterComponent
extends Node

## 親ノードをサイン波で上下にふわふわ動かすコンポーネント
## Node2D, Control (UI), Node3D に対応しています。

# 揺れ幅(ピクセル単位、または3Dの単位)
@export var amplitude: float = 10.0

# 揺れるスピード
@export var speed: float = 2.0

var _time: float = 0.0
var _initial_y: float = 0.0
var _parent: Node

func _ready() -> void:
	_parent = get_parent()
	
	# 親の型をチェックし、現在のY座標を「基準点」として記憶する
	if _parent is Node2D or _parent is Control:
		_initial_y = _parent.position.y
	elif _parent is Node3D:
		_initial_y = _parent.position.y
		
	# 複数のオブジェクトが完全に同期して動くと不自然なので、
	# 開始時間をランダムにずらして「バラつき」を出します
	_time = randf_range(0.0, 100.0)

func _process(delta: float) -> void:
	if not _parent:
		return
		
	# 時間を進める
	_time += delta * speed
	
	# サイン波を計算(-1.0 〜 1.0 の間を行き来する)
	# それに揺れ幅(amplitude)を掛ける
	var offset = sin(_time) * amplitude
	
	# 基準点 + オフセットの位置に移動させる
	if _parent is Node2D or _parent is Control:
		_parent.position.y = _initial_y + offset
	elif _parent is Node3D:
		_parent.position.y = _initial_y + offset

コードのポイント「サイン波とは?」

sin(_time) という関数は、時間が進むにつれて -1 から 1 の間を滑らかに行ったり来たりします。

これに amplitude(揺れ幅)を掛けることで、「上に10ピクセル、下に10ピクセル」といった動きを作っています。物理演算を使わないので、処理がとても軽く、動きが完全に予測可能です。


ステップ2:実際に使ってみよう

  1. 揺らしたいオブジェクト(例:GemのSpriteや、UIのTextureRect)を選択します。
  2. 「子ノードを追加」(+ボタン)をクリック。
  3. 検索バーに「Floater」と入力し、FloaterComponentを選びます。

これで再生してみてください。アイテムがその場でふわふわし始めるはずです!

ステップ3:動きを調整する(レシピ集)

インスペクターで数値をいじることで、動きの性格をガラッと変えられます。

  • ゆっくり大きな揺れ(浮遊アイテム向け)
    • Amplitude: 10 (2D) / 0.5 (3D)
    • Speed: 2
    • 解説: 水中にいるような、ゆったりとした動きになります。
  • 小刻みに震える(UIの注目アイコン向け)
    • Amplitude: 3
    • Speed: 10
    • 解説: 「ここに注目!」と言わんばかりの、プルプルした元気な動きになります。
  • 不安な揺れ(ホラー演出など)
    • Amplitude: 1
    • Speed: 0.5
    • 解説: 止まっているように見えて、実は微妙に動いている…という不気味さを出せます。

注意点:移動するキャラに使う場合

このコンポーネントは**「Y座標(高さ)」を毎フレーム強制的に上書き**します。

そのため、ジャンプしたり階段を登ったりするキャラクターの「ルート(根元)ノード」に直接つけると、Y座標が固定されて動けなくなってしまいます。

移動するキャラクターに浮遊感を出したい場合は、以下のように構成を分けましょう。

  • CharacterBody (移動ロジックはここ)
    • Visual (見た目のスプライトやモデル) ← ここにFloaterをつける!
      • FloaterComponent

こうすれば、キャラクター全体は移動しつつ、見た目だけがその相対座標の中でふわふわ揺れるようになります。