[Deep Dive into AGMaker] Plugin Node - Rotate GameObject to Face Direction of Motion

License Agreement

You may freely use or modify this plugin in Action Game Maker for any purpose, including creating free or commercial projects.
However, please do not redistribute it. Attribution is not required but is appreciated.

Plugin Effect

This plugin is named ArkAgmRotateToVelocity.
Its function is to rotate a game object every frame so that its local physical “right side” always points in the direction of its actual velocity.

Key Points

  • You must specify a GameObject.
  • You can set a minimum squared velocity threshold (using squared values is more performant). The script will only activate when the actual velocity exceeds this value.
  • You can choose between instant and smooth rotation modes.
  • In smooth mode, you can set a value to control how fast the rotation occurs.
  • The original idea was that if you have a bullet object whose animation always faces right, combining it with this script would allow it to rotate 360° according to its actual direction of motion.

Core

Steps

  1. Select the GameObject node.
  2. Press Ctrl+A to add a node of type Node, and rename it ArkAgmRotateToVelocity.
  3. Select ArkAgmRotateToVelocity and add an empty GDScript.
  4. Copy the entire script below and paste it into the script editor, then save.
  5. When the ArkAgmRotateToVelocity node is selected, you can adjust the parameters in the Inspector to enable features like smooth rotation as needed.

Script

class_name ArkAgmRotateToVelocity extends Node

enum RotationMode {
	INSTANT,     # Instant rotation
	SMOOTH,      # Smooth rotation
}

@export var game_object: GameObject
@export var rotation_mode: RotationMode = RotationMode.INSTANT  # Rotation mode
@export var rotation_speed: float = 5.0    # Rotation speed (used when SMOOTH mode is active)
@export var min_velocity_squared: float = 0.1  # Minimum squared velocity to trigger rotation

func _ready() -> void:
	if not game_object:
		# Try to use the parent node as game_object
		var parent = get_parent()
		if parent and parent is GameObject:
			game_object = parent
		else:
			printerr("[ArkAgmRotateToVelocity] game_object is not set and parent is not a GameObject")

func _physics_process(delta: float) -> void:
	if not game_object:
		return
	
	var velocity: Vector2 = game_object.get_real_velocity()
	
	# Do not rotate if velocity is too low
	if velocity.length_squared() < min_velocity_squared:
		return
		
	# Calculate target angle (direction of velocity)
	var target_angle = velocity.angle()
	
	match rotation_mode:
		RotationMode.INSTANT:
			# Instantly rotate to target angle
			game_object.rotation = target_angle
		RotationMode.SMOOTH:
			# Smoothly rotate to target angle
			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)

JatkRotateToMovementDemo.gd (5.5 KB)

1 Like