Smooth camera follow instead of wagging with animation of character

Viewed 1090

All I want is for my camera to follow smooth, but it keeps following the animation motion which I get:

Video screen shot of the problem

I mostly understand what the problem is but I have tried 100 different solutions with no positive results.

My first thought is to create an avatar parent that houses the children both the player and the camera and then the camera would stay inside. But the parent doesn't move with the child... makes sense.

So I manually matched position through update and late update but then for some reason the whole game object falls through the floor.

So I attached a collider to the parent, and it still falls through. I am using photon so I can't move the rigid body to the parent because photon view requires it.

I have also tried to parent the camera to the root game object hoping there would be no sway... fail!

Even that screencapture is using vector3 Slerp, I have tried lerp but it's linear interpretation so even if it solved it Slerp makes more sense for me.

I have though that maybe if I offset the rotation with negative of the value that might solve it but then if I rotate my character on purpose than I hit a problem.

Although this is only one variation I know that it might help:

/// <summary>
///   puts the camera in the correct location andsets the camera to look at the hero
/// </summary>
public void position_the_camera()
{

    //camera.transform.position = player.camera_position.transform.position;

    camera.transform.position = Vector3.Slerp(
        player.camera_position.transform.position,
        player.camera_position.transform.position - camera_offset,
        camera_follow_smoothing_time);

    camera.transform.LookAt(player.look_at_target.transform);
}
2 Answers

Apply Tolerance to movement, i.e., do not move the camera if the difference in player position or rotation is lower than a specified limit.

You will personally have to experiment with the values to find what suits your game the best.

If the limits are too small, the camera will wag/vibrate. If the limits are too large, the video will be choppy/jerky.

It's been a while since I last used Unity and cannot help with the code. Sorry.

I realized something the only time my camera should move left or right is when I want it to.

So instead of a tolerance add a Boolean flag to allow for left or right movement and then only allow movement when the flag is true when that inputs is != 0 and so the camera should always face the transform.forward direction.

Update

I ended up doing something entirely different than any of these recommendations or my own solution.

I realized I had a look at target attached to my game object as well as a camera position game object meaning.

camera.main.transform.position = camera_position.transform.position

lookat(look_at_target.transform) 

but that was the problem because both of those were following root motion so instead I have done

/// <summary>
///   puts the camera in the correct location andsets the camera to look at the hero
/// </summary>
public void position_the_camera()
{
    /// the player is 
    if (player.animations.movement.y != 0 || player.actions.has_cart)
    {
        rotation_factor += player.interactions.ui.rotate().x * rotation_retardant;
        camera_offset.x = Mathf.Sin(rotation_factor) * 5;

        camera_offset.z = Mathf.Cos(rotation_factor) * -5;
    }
    else {
        Debug.Log(player.animations.animator.rootRotation.y);
    }


    //camera.transform.position = gameObject.transform.position + camera_offset;

    camera.transform.position = Vector3.Slerp(
        gameObject.transform.position,
        gameObject.transform.position + camera_offset,
        camera_follow_smoothing_time);

    camera.transform.LookAt(transform);
}

It's still up for modification because it works perfectly when the character is rotating based on script but not when I'm animating the turn with root motion.

But much better right now.

Final update

/// <summary>
///   puts the camera in the correct location andsets the camera to look at the hero
/// </summary>
public void position_the_camera()
{

    /// the player is 
    if (player.animations.movement.y != 0 || player.actions.has_cart)
    {
        player_rotation_factor += player.interactions.ui.rotate().x * player_rotation_retardant;

    }
    else {
        player_rotation_factor = -player.animations.animator.rootRotation.eulerAngles.y * (Mathf.PI / 180);
    }

    camera_offset.x = Mathf.Sin(player_rotation_factor) * player_rotation_scalar;

    camera_offset.z = Mathf.Cos(player_rotation_factor) * -player_rotation_scalar;

    //camera.transform.position = gameObject.transform.position + camera_offset;

    camera.transform.position = Vector3.Lerp(
        gameObject.transform.position,
        gameObject.transform.position + camera_offset,
        camera_follow_smoothing_time);

    camera.transform.LookAt(transform);
}

The code allows the UI to create the scripted rotation and follows trig rules.

The animated turn allows the rootMotion to do the work with euler angles (I forgot about the Euler angles) and since sine and cose require radians I just converted it real quick to radians (pi / 180).

Related