I am trying to get a smooth camera motion with my current camera script. I can get them to work separately but not together I have tried different methods but can’t seem to get it to work correctly
Thanks for your reply. No there not both attached I’m trying to combine the 2 scripts because they both do what I want.
I am trying to get a fixed camera behind the player so if he turns so does the camera so in other words Its always facing the way he’s looking. Then if he walks or runs the camera will follow behind him and once he stops the camera catches up and goes back into position.
Right now the camera turns when the player turns. If I run the scripts separately they do what I want.
using UnityEngine;
using System.Collections;
public class TestCamera : MonoBehaviour
{
public Transform target; // Target to follow
public float targetHeight = 1.7f; // Vertical offset adjustment
public float distance = 12.0f; // Default Distance
public float offsetFromWall = 0.1f; // Bring camera away from any colliding objects
public float maxDistance = 20; // Maximum zoom Distance
public float minDistance = 0.6f; // Minimum zoom Distance
public float xSpeed = 200.0f; // Orbit speed (Left/Right)
public float ySpeed = 200.0f; // Orbit speed (Up/Down)
public float yMinLimit = -80; // Looking up limit
public float yMaxLimit = 80; // Looking down limit
public float zoomRate = 40; // Zoom Speed
public float rotationDampening = 3.0f; // Auto Rotation speed (higher = faster)
public float zoomDampening = 5.0f; // Auto Zoom speed (Higher = faster)
public float MaximumDegreesRot = 90f;
LayerMask collisionLayers = -1; // What the camera will collide with
// public bool lockToRearOfTarget;
public bool allowMouseInputX = true;
public bool allowMouseInputY = true;
private float xDeg = 0.0f;
private float yDeg = 0.0f;
private float currentDistance;
public float desiredDistance;
private float correctedDistance;
// private bool rotateBehind; appearing not used
public GameObject userModel;
public bool inFirstPerson;
Rigidbody myRigidbody = null;
void Start()
{
Vector3 angles = transform.eulerAngles;
xDeg = angles.x;
yDeg = angles.y;
currentDistance = distance;
desiredDistance = distance;
correctedDistance = distance;
// Make the rigid body not change rotation
if (myRigidbody)
myRigidbody.freezeRotation = true;
//if (lockToRearOfTarget)
// rotateBehind = true;
}
void Update()
{
if (Input.GetAxis("Mouse ScrollWheel") < 0)
{
if (inFirstPerson == true)
{
minDistance = 10;
desiredDistance = 15;
userModel.SetActive(true);
inFirstPerson = false;
}
}
if (desiredDistance == 10)
{
minDistance = 0;
desiredDistance = 0;
userModel.SetActive(false);
inFirstPerson = true;
}
}
//Only Move camera after everything else has been updated
void LateUpdate()
{
// Don't do anything if target is not defined
if (!target)
return;
// Vector3 vTargetOffset3;
// If either mouse buttons are down, let the mouse govern camera position
if (GUIUtility.hotControl == 0)
{
if (Input.GetKey(KeyCode.LeftControl))
{
}
else
{
if (Input.GetMouseButton(1))
{
//Check to see if mouse input is allowed on the axis
if (allowMouseInputX)
xDeg += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
if (allowMouseInputY)
yDeg -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
}
}
}
ClampAngle(yDeg);
// Set camera rotation
//Changed the below out to try to fix the camera rotation but produces leaning camera, May fix with Camera arm
//Quaternion rotation = Quaternion.Euler(yDeg, xDeg, 0);
Quaternion targetRot = Quaternion.Euler(yDeg, xDeg, 0) * target.rotation;
Quaternion rotation = Quaternion.RotateTowards(transform.rotation, targetRot, (float)MaximumDegreesRot);
transform.rotation = rotation;
// Calculate the desired distance
desiredDistance -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs(desiredDistance);
desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance);
correctedDistance = desiredDistance;
// Calculate desired camera position
Vector3 vTargetOffset = new Vector3(0, -targetHeight, 0);
Vector3 position = target.position - (rotation * Vector3.forward * desiredDistance + vTargetOffset);
// Check for collision using the true target's desired registration point as set by user using height
RaycastHit collisionHit;
Vector3 trueTargetPosition = new Vector3(target.position.x, target.position.y + targetHeight, target.position.z);
// If there was a collision, correct the camera position and calculate the corrected distance
bool isCorrected = false;
if (Physics.Linecast(trueTargetPosition, position, out collisionHit, collisionLayers))
{
correctedDistance = Vector3.Distance(trueTargetPosition, collisionHit.point) - offsetFromWall;
isCorrected = true;
}
// For smoothing, lerp distance only if either distance wasn't corrected, or correctedDistance is more than currentDistance
currentDistance = !isCorrected || correctedDistance > currentDistance ? Mathf.Lerp(currentDistance, correctedDistance, Time.deltaTime * zoomDampening) : correctedDistance;
// Keep within limits
currentDistance = Mathf.Clamp(currentDistance, minDistance, maxDistance);
// Recalculate position based on the new currentDistance
position = target.position - (rotation * Vector3.forward * currentDistance + vTargetOffset);
//Finally Set rotation and position of camera
transform.rotation = rotation;
transform.position = position;
}
void ClampAngle(float angle)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
yDeg = Mathf.Clamp(angle, -60, 80);
}
}
I think thats the one i was using in my RPG bit this should help you compare. WARNING its a little buggy as if you rotate the player the camera doesnt lock to the rear of the target.
You could extract them into different methods and call them from your FixedUpdate(), so that it moves first, then rotates, and then put your LookAt into a third method and call it after the other two. That’s what I ended up doing with my camera.