Smooth Camera Pivoting with Stopping Points

New to programming.
I’m trying to create a camera that smoothly pivots around the player in 45 degree intervals on only the y-axis, snapping to and stopping at the 8 cardinal directions around the player, single button press for each direction, no holding. But I’ve been trying for a day and a half with no progress.
I’ve attached the Camera3d to a Node3D pivot point and have the rotation working with simple “If action just pressed: .y + 45 degrees” code, but it’s instant instead of gradual. I’ve tried a bunch of interpolating methods but none of them are working for me, either not made for a flat value input and spinning forever, rotating on axes besides the y as well, or just crashing completely.
The most promising idea I had was creating a second pivot node and rotating it first, then interpolating between its new transform and the camera’s, but I never got it working.
I’m definitely missing something but I can’t even find a similar kind of camera being talked about to find some direction and feel lost. What method should I be using here?
My nodes are set up like this:
Node3D (script on this)
camera_target (Node3D PivotPoint)
Camera3D

And here is only code I have that works

extends Node3D

@export var camera_target : Node3D

func _process(delta):
if Input.is_action_just_pressed(“Rotate_L”):
camera_target.rotation.y += deg_to_rad(45)
if Input.is_action_just_pressed(“Rotate_R”):
camera_target.rotation.y += deg_to_rad(45)

You could try storing the desired rotation in a variable and using lerp_angle.

extends Node3D

@export var camera_target : Node3D
var target_angle: float

func _ready():
    target_angle = camera_target.rotation.y

func _process(delta):
    if Input.is_action_just_pressed("Rotate_L"):
        target_angle += deg_to_rad(45)
    if Input.is_action_just_pressed("Rotate_R"):
        target_angle -= deg_to_rad(45)

    # Change the constant (2) until you get the desired rotation speed
    var rot_weight: float = clampf(2 * delta, 0, 1)
    camera_target.rotation.y = lerp_angle(camera_target.rotation.y, target_angle, rot_weight)

I’ll admit I’m not 100% this’ll work, so sorry if it doesn’t, but hopefully it helps in some way.

1 Like

Thank you so much that works perfectly.

1 Like