• Godot Help
  • Move towards target location and rotation

I have been trying for hours to get a camera to move from one location and rotation to another.

Below is an example of how I have tried to get this to work. I am not sure if I am even bothered about 'lerping' but that might make sense. I just want to know what would be the best way to animate the location and rotation towards a new 'target'.

if rotation_lerp < 1:
	rotation_lerp += delta * lerp_speed
elif rotation_lerp > 1:
	rotation_lerp = 1
	
var a = Quaternion(camera.basis)
var target_rotation_node = Node3D.new()
target_rotation_node.rotation_degrees = target_rotation
var b = Quaternion(target_rotation_node.basis)
var c = a.slerp(b, rotation_lerp)

var target_xform : Transform3D = Transform3D(Basis(c), follow_this.global_position + target_offset)
camera.global_transform = target_xform

Here is an example of what I am trying to achieve but it only seems to work with locations. Not rotations.
https://kidscancode.org/godot_recipes/4.x/3d/interpolated_camera/

  • xyz replied to this.

    zerohootsoliver There are 2 parts to this problem.

    1. Figuring out the exact wanted camera position/orientation in respect to target.
    2. Gradually getting the camera to that position/orientation to look like it's smoothly catching up.

    If you solve 1, you'll get the "hard" (or instant) camera follow. You should focus on that first.

    So number 1. You need to define 2 constant points expressed in target's local space

    • camera position
    • camera lookat point

    Now you have to do the following:

    • transform those two points into global space
    • move the camera to the position point
    • make the camera look at the lookat point.

    Do this every frame, and voila, you now have the "hard" follow. Set this up and then we can talk about smoothing and catching up.

      xyz I created a node of type Marker3D called NewCameraTransform to represent the target location and rotation. I also created a Marker3D node called LookAt that is a child of the camera. I tried to position this to the forward unit vector of the NewCameraTransform (relative to the camera). so that when I look_at the %LookAt node from the camera node, it matches the NewCameraTransform node's rotation (rotating by the Y axis).

      Changing it so that the rotate_y gets called on the camera instead of the NewCameraTransform works but I want to make it so that I can use the look_at function like what you said, in order to use it as a way to move from its current rotation to the new one.

      The code I have written:

      $NewCameraTransform.rotate_y(0.5)
      
      
      #print($NewCameraTransform.basis.z)
      %LookAt.position = $NewCameraTransform.basis.z
      camera.look_at(%LookAt.position, Vector3.UP)

        zerohootsoliver To clarify, the only reason I have a node called NewCameraTransform is to use it as a node to copy from. So that when I reference it, I can use it to position the LookAt node.

        This is because I want to be able to convert a radians rotation to a unit vector that can be used to position the LookAt node so that I can use that node to move the position which the camera is looking at.

        This is to achieve the goal of getting from one rotation to another rotation.

        zerohootsoliver
        Blargh! 😃
        You're making things more complicated than they need to be. And I think our terminologies are not in tune. By "target" I mean the player entity that camera follows.

        Let's start over. Forget bases, quaternions and rotations in general.

        We want our camera to follow the player avatar which happens to be a rabbit. We only need two nodes:

        • camera - The Camera3D node.
        • rabbit - The player avatar that runs around the meadow. Any 3d node will do.

        We want the camera to always be positioned and oriented the same way relative to the rabbit. So the picture of rabbit is always the same size and from the same angle. Exactly as if camera was rabbit's child node (but it isn't)

        To position the camera in such a way we need two points:

        • the point at which camera hovers
        • the point it looks at

        These two points are always the same from rabbit's perspective. The rabbit shall complain: "This damn camera is following me around, hovering at 2 meters above the ground and it's always 5 meters behind me and 1 meter on the right. Always. And it's always aimed at the meadow exactly 1 meter in front of me."

        So the two points the camera is interested in are:

        • position: (1, 2, 5) from rabbit's nose
        • lookat: (0, 0, -1) from rabbit's nose

        The camera always wants to be/look at these points. Otherwise the rabbit's picture will not be nice. But the problem is; the camera is not the rabbit. It needs to know where those points are in respect to the giant pine tree in the center of the meadow (global space), not in respect to rabbit's nose. So it can easily find where to go/look starting from that giant pine tree.

        Camera then brings along its robot friend for help, and says to them:

        var i_must_go_to = rabbit.to_global( Vector3(1, 2, 5) )
        var i_must_look_at = rabbit.to_global( Vector3(0, 0, -1) )
        self.global_position = i_must_go_to
        self.look_at(i_must_look_at, Vector3.UP)

        Finally the camera smiles and says: I will do this every frame, and rabbit will not ever be able to hide from my gaze.