Hello! I've been stumped on a core part of my game project for the past couple of days. It basically boils down to: I'm trying to figure out a good way to have the player orbit another object using A and D, but also be able to get closer or farther from it using W and S, as a sort of "lock-on system". I'm not really good when it comes to 3D things or math, and I've exhausted my extent of personal and Google knowledge. I've got some code below but all it was for was the orbiting feature and I'm all for scrapping it if there's a better way. Thank you in advance!

var move_base = .05
    
var move_dist = (Input.get_action_strength("move_down") - Input.get_action_strength("move_up")) * move_base
var move_orb = (Input.get_action_strength("move_right") - Input.get_action_strength("move_left")) * move_base
    
# Rotation variables
# Subtract origin point from target's position
var pivot_radius = Vector3.ZERO - target.global_translation
    
var pivot_transform = Transform(transform.basis, target.global_translation)

# Rotate around target
transform = pivot_transform.rotated(Vector3(0, 1, 0), move_orb).translated(pivot_radius)

As well as that I've also attached a picture with the core idea of what I'm trying to do, that being having a player orbit along the red circle as well as being able to get closer or farther from the selected enemy along that line that bisects them.

  • Alright, I figured it out and I'll attach my final results below. I ended up using a super simple way of rotating velocity around a point, being:

    var move_base = 5 # Base speed of player
    var velocity = Vector3(0, 0, 0) # Starting Vector3 point.
    
    # I spent two days working on this only for it to be as easy as:
    # Look at target every frame you update movement and rotate your final velocity around it. _ノ乙(、ン、)_
    
    # Establish movement variables which will be used for strafing and distance RESPECTIVELY
    var move_orbit = (Input.get_action_strength("move_right") - Input.get_action_strength("move_left")) * move_base
    var move_dist = (Input.get_action_strength("move_down") - Input.get_action_strength("move_up")) * move_base
    
    # Make current turn character look at target.
    look_at(target.global_translation, Vector3(0, 1, 0))
    
    # Modify velocity
    velocity.x = move_orbit
    velocity.z = move_dist
    
    # Return velocity with modified angle to target.
    return velocity.rotated(Vector3(0, 1, 0), get_rotation().y)

    Which allowed me to get the finalized product being:

That looks overcomplicated. You don't really need math here. You can just use the node system.

Attach a Spatial node (Node3D in Godot 4, I believe) to your centre object. Then attach the rotating object to the Spatial. Set the local translation x of the rotating object to some value larger than 0.

You can rotate the object by changing the local rotation y of the Spatial.

You can move the rotating object in/out by changing the local translation x of the rotating object.

    Zini Does that work if the player is the one controlling the rotating object?

    Alright, I figured it out and I'll attach my final results below. I ended up using a super simple way of rotating velocity around a point, being:

    var move_base = 5 # Base speed of player
    var velocity = Vector3(0, 0, 0) # Starting Vector3 point.
    
    # I spent two days working on this only for it to be as easy as:
    # Look at target every frame you update movement and rotate your final velocity around it. _ノ乙(、ン、)_
    
    # Establish movement variables which will be used for strafing and distance RESPECTIVELY
    var move_orbit = (Input.get_action_strength("move_right") - Input.get_action_strength("move_left")) * move_base
    var move_dist = (Input.get_action_strength("move_down") - Input.get_action_strength("move_up")) * move_base
    
    # Make current turn character look at target.
    look_at(target.global_translation, Vector3(0, 1, 0))
    
    # Modify velocity
    velocity.x = move_orbit
    velocity.z = move_dist
    
    # Return velocity with modified angle to target.
    return velocity.rotated(Vector3(0, 1, 0), get_rotation().y)

    Which allowed me to get the finalized product being: