hi, perhaps someone can point me to a nice working script for my requirements.
i want my 3rd person camera to smoothly transition from one object to another. the transition should take into account that the next object may be very close, say 0.01m away or may be far, say 10m away, so the transition would take longer for the further one and hopefully not look jumpy.
but, the target object will be moving so the camera needs to catch up to the new position faster as the object moves faster.
also i need it to zoom out automatically if necessary so both original and target object can be seen during the transition, then zoom back in as the target is approached or slows down, and the zoom needs to be smooth.
i know about Vector3.lerp and i have a system working now but its far from perfect. i’m hoping to find something that is know to work well.
oh, and in addition to all that, the user can also add pan, rotate and zoom with the mouse as all this is happening.
thanks
Just to help you get an answer, let me ask; what is your question?
What did you try? What is the issue with your approach?
I don’t think you’ll get people to just write a script for you and spoon feed you.
For your camera movement, I can suggest that you move at a constant speed relative to the distance to the object.
For example determine that you want the camera to catch up within 2 seconds.
From there, in your update you can check the distance between object and camera, and move by (Time.deltaTime / 2 seconds) * distance. That approach has the drawback that you’ll never actually reach the object, but you could set a minimum speed to fix that.
as for the panning, just set up a function such that panning goes up as distance goes up.
my question is if someone can point me to a working script example. i’ve tried a simple approach of lerp’ing between the old and new objects with a fixed lerp value and also a dynamic one based on the intervening distance and/or speed but i wasn’t happy with the results.
i also tried moving 10% closer to the current position of the target from the current position of the camera on every camera LateUpdate, knowing that will be a log type move (slows down as it gets closer) and that looks better but still a bit jumpy
i think i understand the basics but i’m sure many people have done this before and i was hoping to find a nice working example
if anyone interested, i made a nice script that does all of the above
private Vector3 lookat_velocity = Vector3.zero;
private float lookat_smoothTime = .3f;
private float autoSpeedZoom_distance = 0; //-ve = zoom out, +ve = zoom in
private float autoSpeedZoom_smoothTime = .2f;
private float autoSpeedZoom_distance_v = 0;
private float autoSizeZoom_distance = 0; //-ve = zoom out, +ve = zoom in
private float autoSizeZoom_smoothTime = .2f;
private float autoSizeZoom_distance_v = 0;
void LateUpdate ()
{
// THIS IS WHERE CAMERA MOVING, ROTATING AND ZOOMING HAPPENS
//
// handle camera panning
//
curLookAtPosition = Vector3.SmoothDamp(curLookAtPosition, lookAtObject.transform.position, ref lookat_velocity, lookat_smoothTime);
// Debug.Log("CameraControl LateUpdate velocity=" + velocity.magnitude);
curLookAtPosition.x += userPan.y;
curLookAtPosition.y += userPan.x;
//
// handle auto zooming on fast moving ojects
//
Rigidbody rb = lookAtObject.GetComponent<Rigidbody>();
if (rb != null)
{
float lookAtObject_v = rb.velocity.magnitude;
// range from about 0 to about 24 for flying brain
float d = -lookAtObject_v / 3;
autoSpeedZoom_distance = Mathf.SmoothDamp(autoSpeedZoom_distance, d, ref autoSpeedZoom_distance_v, autoSpeedZoom_smoothTime);
//Debug.Log ("CameraControl lookAtObject_v=" + lookAtObject_v + " autoSpeedZoomDistance=" + autoSpeedZoom_distance);
}
//
// handle auto zooming based on size of lookat ojects
//
Collider col = lookAtObject.GetComponent<Collider>();
if (col != null)
{
Vector3 size = col.bounds.size;
float biggest = Mathf.Max (size.x, size.y);
biggest = Mathf.Max (biggest, size.z); // about .13 for a domino and 1.5 for a zombie
// .13 -> 0 1.5->-2
float d = 0.13f - biggest * 1.1f;
autoSizeZoom_distance = Mathf.SmoothDamp(autoSizeZoom_distance, d, ref autoSizeZoom_distance_v, autoSizeZoom_smoothTime);
//Debug.Log ("CameraControl biggest=" + biggest);
}
//
// handle camera rotation, zoom and lookat
//
//Vector3 lookAtpositionB = lookAt.position;
Quaternion userRotation = Quaternion.Euler (userRot.x, userRot.y, 0);
Vector3 userZoomDistance = wheelZoomDistance;
userZoomDistance.z += autoSpeedZoom_distance + autoSizeZoom_distance;
if (wheelZoomEnabled) {
// mouse wheel is + or - 0.1 when moving, else 0 when stationarry, use it to tweek wheelZoomDistance.z
float wheelPos = Input.GetAxis ("Mouse ScrollWheel");
wheelZoomDistance.z += wheelPos * mouseZoomSpeed;
//Debug.Log ("CameraControl wheelZoomDistance.z=" + wheelZoomDistance.z);
if (wheelZoomDistance.z > -0.1f)
wheelZoomDistance.z = -0.1f; // max zoom in
}
transform.position = curLookAtPosition + userRotation * userZoomDistance;
transform.LookAt (curLookAtPosition);
}