- Home /
How can I Make my orbit camera more smooth?
I have this camera script that orbits when I press the right mouse button but its all jerky how can I smooth its movement? also it seems it remembers where it was last time I pressed the right mouse but obviously first time player press right mouse button the camera is pointing to the ground, I dont quite like that >_<
public class CameraScript : MonoBehaviour {
//camera variables
public Transform cameraLookAtTaret = null;
private int mouseDown;
private GameObject MiTarget = null;
private float height = 0.0f;
private float rotationDamping = 3.0f;
private float heightDamping = 2.0f;
private float distance = 2.0f;
private float yMinLimit = -20;
private float yMaxLimit = 80;
private float xMinLimit = -100;
private float xMaxLimit = 100;
private float xSpped = 250;
private float ySpeed = 120;
private float x = 0.0f;
private float y = 0.0f;
private float distanceMin = 1f;
private float distanceMax = 4f;
/// <summary>
/// Here is where all the mouse input takes place, if you hold now mouse button down it will just follow your character and zoom in and out
/// if you hold down the right mouse button you can rotate around your player and zoom in and out
/// if you hold both left and right mouse button it will also turn your player
/// </summary>
void Start(){
MiTarget= GameObject.FindGameObjectWithTag("Target");
if (MiTarget != null){
cameraLookAtTaret = MiTarget.transform;
}
var angles = gameObject.transform.eulerAngles;
x = angles.x;
y = angles.y;
}
float ClampAngle(float angle, float min, float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
void LateUpdate(){
if (cameraLookAtTaret != null){
var wantedRotationAngle = cameraLookAtTaret.eulerAngles.y;
var wantedHeight = cameraLookAtTaret.position.y + height;
var currentRotationAngle = gameObject.transform.eulerAngles.y;
var currentHeight = gameObject.transform.position.y;
currentRotationAngle = Mathf.LerpAngle(currentRotationAngle, wantedRotationAngle, rotationDamping * Time.deltaTime);
currentHeight = Mathf.Lerp(currentHeight, wantedHeight, heightDamping * Time.deltaTime);
var currentRotation = Quaternion.Euler(0, currentRotationAngle, 0);
gameObject.transform.position = cameraLookAtTaret.position;
gameObject.transform.position -= currentRotation * Vector3.forward * distance;
gameObject.transform.position = new Vector3(gameObject.transform.position.x, currentHeight, gameObject.transform.position.z);
gameObject.transform.LookAt(cameraLookAtTaret);
}
if (Input.GetMouseButton(1))
{
x += Input.GetAxis("Mouse X") * xSpped * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
y = ClampAngle(y, yMinLimit, yMaxLimit);
x = ClampAngle(x, xMinLimit, xMaxLimit);
var rotation = Quaternion.Euler(y, x, 0);
var currentRotationAngle = gameObject.transform.eulerAngles.y;
var currentRotation = Quaternion.Euler(0, currentRotationAngle, 0);
gameObject.transform.position = cameraLookAtTaret.position;
gameObject.transform.position -= currentRotation * Vector3.forward * distance;
var currentHeight = gameObject.transform.position.y;
gameObject.transform.position = new Vector3(gameObject.transform.position.x, currentHeight, gameObject.transform.position.z);
gameObject.transform.rotation = rotation;
distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel")*5, distanceMin, distanceMax);
}
}
}
I didn't make the original and there are things I still dont understand, but I have modify quite a bit of it.
Answer by Roland1234 · Dec 11, 2013 at 12:54 AM
The main cause of your jerky motion is due to the order of your calculations. Without going into too much detail you can simplify the LateUpdate method to this:
void LateUpdate()
{
if(cameraLookAtTaret == null)
{
return;
}
if(Input.GetMouseButton(1))
{
x = ClampAngle(x - (Input.GetAxis("Mouse Y") * xSpeed * 0.02f), xMinLimit, xMaxLimit);
y = ClampAngle(y + (Input.GetAxis("Mouse X") * ySpeed * 0.02f), yMinLimit, yMaxLimit);
distance = Mathf.Clamp(distance - (Input.GetAxis("Mouse ScrollWheel") * 5), distanceMin, distanceMax);
transform.eulerAngles = new Vector3(x, y, 0.0f);
transform.position = cameraLookAtTaret.position - (transform.forward * distance);
}
else
{
var wantedRotationAngle = cameraLookAtTaret.eulerAngles.y;
var wantedHeight = cameraLookAtTaret.position.y + height;
var rotationT = rotationDamping * Time.deltaTime;
var currentXRotation = Mathf.LerpAngle(transform.eulerAngles.x, 0.0f, rotationT);
var currentYRotation = Mathf.LerpAngle(transform.eulerAngles.y, wantedRotationAngle, rotationT);
var currentHeight = Mathf.Lerp(transform.position.y, wantedHeight, heightDamping * Time.deltaTime);
transform.eulerAngles = new Vector3(x = currentXRotation, y = currentYRotation, 0.0f);
transform.position = cameraLookAtTaret.position - (transform.forward * distance);
transform.position.Set(transform.position.x, currentHeight, transform.position.z);
transform.LookAt(cameraLookAtTaret);
}
}
Which should eliminate the jerkiness. Also note that you will not be able to clamp the angles in the way you are currently attempting - you'll have to translate the euler angles into the range you are defining your limits in then translate them back.
Thank you! I was having a similar problem where I continuously set the camera`s position while trying it to look at a game object. I even tried moving the positioning to LateUpdate, and then the looking at in the LateUpdate but didn't occur to me to move both :DDD Thanks again!
the script is awsm but the mouse is stuck at the center of the object i.e. whenever we might move it always translates back to the center . i desperately need this script could anyone please solve the bugs. @Roland1234 @apomarinov1 @raycosantana ps: i just want a smooth mouse orbit script nothing to move my object
@Redeemer86 i am in dire need of a smooth mouse orbit script which on leaving the mouse button translates the camera a little bit more in the direction on which the mousebuttonup happened i.e. WHEN I CLIC$$anonymous$$ THE RIGHT $$anonymous$$OUSE BUTTON IT ROTATES IN THE ORBIT AND WHEN I LEAVE IT JUST $$anonymous$$OVES A LITTLE BIT EXTRA DISTANCE IN THE SA$$anonymous$$E DIRECTION(LI$$anonymous$$E GIVING IT A SPIN LOO$$anonymous$$). also in this script the issue might have been resolved but the camera is always stuck under my gameobject.
Answer by deadshot · Oct 22, 2014 at 05:38 AM
using UnityEngine;
using UnityEngine;
using System.Collections;
//[AddComponentMenu("Camera-Control/Mouse drag Orbit with zoom")]
public class rotateonmouse : MonoBehaviour
{
public Transform target;
public float distance = 5.0f;
public float xSpeed = 120.0f;
public float ySpeed = 120.0f;
public float yMinLimit = -20f;
public float yMaxLimit = 80f;
public float distanceMin = .5f;
public float distanceMax = 15f;
public float smoothTime = 2f;
float rotationYAxis = 0.0f;
float rotationXAxis = 0.0f;
float velocityX = 0.0f;
float velocityY = 0.0f;
// Use this for initialization
void Start()
{
Vector3 angles = transform.eulerAngles;
rotationYAxis = angles.y;
rotationXAxis = angles.x;
// Make the rigid body not change rotation
if (rigidbody)
{
rigidbody.freezeRotation = true;
}
}
void LateUpdate()
{
if (target)
{
if (Input.GetMouseButton(1))
{
velocityX += xSpeed * Input.GetAxis("Mouse X") * 0.02f;
velocityY += ySpeed * Input.GetAxis("Mouse Y") * 0.02f;
}
rotationYAxis += velocityX;
rotationXAxis -= velocityY;
rotationXAxis = ClampAngle(rotationXAxis, yMinLimit, yMaxLimit);
Quaternion fromRotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, 0);
Quaternion toRotation = Quaternion.Euler(rotationXAxis, rotationYAxis, 0);
Quaternion rotation = toRotation;
Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
Vector3 position = rotation * negDistance + target.position;
transform.rotation = rotation;
transform.position = position;
velocityX = Mathf.Lerp(velocityX, 0, Time.deltaTime * smoothTime);
velocityY = Mathf.Lerp(velocityY, 0, Time.deltaTime * smoothTime);
}
}
public static float ClampAngle(float angle, float min, float max)
{
if (angle < -360F)
angle += 360F;
if (angle > 360F)
angle -= 360F;
return Mathf.Clamp(angle, min, max);
}
}
its a smooth camera orbit and the camera stays at the last position s long as the game mode is on