# \[AGMaker Dive\] プラグインノード：移動速度の方向に GameObject を回転させる

**URL:** <https://guild.rpgmakerofficial.com/t/topic/224>\
**Category:** 一般\
**Tags:** tutorial, english\
**Created:** [2025 年 6 月 14 日午後 12:00 UTC](https://guild.rpgmakerofficial.com/t/topic/224 "2025-06-14T12:00:10Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Justus](https://sea2.discourse-cdn.com/flex002/user_avatar/guild.rpgmakerofficial.com/justus/32/55_2.png) [@Justus](https://guild.rpgmakerofficial.com/u/Justus)\
**Post date:** [2025 年 6 月 14 日午後 12:00 UTC](https://guild.rpgmakerofficial.com/t/topic/224/1 "2025-06-14T12:00:10Z")

</div>

## ライセンス契約

このプラグインは、無料プロジェクトまたは商用プロジェクトの作成を問わず、Action Game Maker 内で自由に使用または変更することができます。ただし、再配布は行わないでください。  
クレジットの表示は必須ではありませんが、歓迎いたします。

## プラグインの効果

このプラグインの名前は `ArkAgmRotateToVelocity` です。その機能は、ゲームオブジェクトを毎フレーム回転させ、ローカル物理の「右側」が実際の速度の方向を常に指すようにすることです。

## 要点

- `GameObject` の指定が必要です。
- 最小有効速度の二乗値を指定できます（二乗値を使用する方が効率的です）。実際の速度がこの値を超えた場合にのみスクリプトが作動します。
- 2 つの回転モード（即座に回転、滑らかに回転）をサポートしています。
- 滑らかに回転するモードでは、回転の速さを表す値を設定できます。
- 当初のアイデアは、アニメーションの方向が常に右を向く弾丸オブジェクトを作成し、このスクリプトによって実際の移動方向に応じて 360°回転できるようにすることでした。

## コア

### 操作手順

1. GameObject ノードを選択します。
2. `Ctrl+A` を押して `Node` 型のノードを追加し、`ArkAgmRotateToVelocity` に名前を変更します。
3. `ArkAgmRotateToVelocity` を選択し、空の GDscript を追加します。
4. 以下のスクリプト全体をコピーしてスクリプトに貼り付け、保存します。
5. `ArkAgmRotateToVelocity` ノードが選択されている状態で、インスペクタでパラメータを必要に応じて調整し、滑らかな回転やその他の機能を有効にするかどうかを決定できます。

### スクリプト

```python
class_name ArkAgmRotateToVelocity extends Node

enum RotationMode {
	INSTANT, # 即時回転
	SMOOTH, # 滑らかな回転
}

@export var game_object: GameObject
@export var rotation_mode: RotationMode = RotationMode.INSTANT # 回転モード
@export var rotation_speed: float = 5.0 # 回転速度（SMOOTH モードを使用する場合）
@export var min_velocity_squared: float = 0.1 # 回転開始の最小速度二乗値

func _ready() -> void:
	if not game_object:
		# 親ノードを game_object として取得しようとする
		var parent = get_parent()
		if parent and parent is GameObject:
			game_object = parent
		else:
			printerr("[ArkAgmRotateToVelocity] game_object が設定されておらず、親が GameObject ではありません")

func _physics_process(delta: float) -> void:
	if not game_object:
		return
	
	var velocity: Vector2 = game_object.get_real_velocity()
	
	# 速度が小さすぎる場合は回転しない
	if velocity.length_squared() < min_velocity_squared:
		return
		
	# 目標角度（速度の方向の角度）を計算
	var target_angle = velocity.angle()
	
	match rotation_mode:
		RotationMode.INSTANT:
			# 目標角度に即時回転
			game_object.rotation = target_angle
		RotationMode.SMOOTH:
			# 目標角度に滑らかに回転
			var current_angle = game_object.rotation
			var angle_diff = wrapf(target_angle - current_angle, -PI, PI)
			game_object.rotation = current_angle + angle_diff * min(1.0, rotation_speed * delta)

```
