So I’m trying to stop this from rotating strangly sometimes. What am I doing wrong here? : Here is the full code :
using UnityEngine;
using System.Collections;
using AppUtils;
public class CameraController : MonoBehaviour {
public Transform target;
public float targetHeight = 1.7f;
public LayerMask collisionLayers = -1;
public float offsetFromWall = 0.1f;
public float sensitivityX = 10.0f; // The `X` `speed` `sensitivity` of the `mouse` in which the camera
// rotates in units
public float sensitivityY = 8.0f; // The `Y` `speed` `sensitivity` of the `mouse` in which the camera
// rotates in units
public bool invertXRotation = false;
public bool invertYRotation = false;
public int switchRotationMode = 1; // Which camera rotation mode to use
// Defaults to mode `1`
// Mode `0` :: { Looks `up` when moving `mouse` `down`... }
// Mode `1` :: { Looks `down` when moving `mouse` `up`... }
public float xVelocity = 200.0f; // The `X` `speed` in which the camera rotates in units
public float yVelocity = 200.0f; // The `Y` `speed` in which the camera rotates in units
public float distance = 5.0f;
public float zoomMindistance = 5.0f;
public float zoomMaxdistance = 20.0f;
public float xMinPitch = -80.0f; // The `minimum` allowed range in which to rotate the camera
// on the `X` axis
public float xMaxPitch = 80.0f; // The `maximum` allowed range in which to rotate the camera
// on the `X` axis
public float yMinYaw = -180.0f; // The `minimum` allowed range in which to rotate the camera
// on the `Y` axis
public float yMaxYaw = 180.0f; // The `maximum` allowed range in which to rotate the camera
// on the `Y` axis
public float zoomRate = 40.0f;
public float zoomDampening = 5.0f;
public float smoothTime = 0.01f; // The `time` it takes for the `camera` to `smoothly` `rotate`
// to its' new rotation
public float rotationDampening = 3.0f;
public float damper = 5.0f; // The `minimum` allowed `damper` for
// `smoothing` camera speed
private float xDeg = 0.0f;
private float yDeg = 0.0f;
private float currentDistance;
private float desiredDistance;
private float correctedDistance;
private float startRotationX = 0.0f; // Default `X` rotation when mouse button is
// not held
private float startRotationY = 0.0f; // Default `Y` rotation when mouse button is
// not held
private Vector3 vTargetOffset;
private void CalculateZoom ( ) {
// Calculate the desired distance for `mouse wheel`
desiredDistance -= Input.GetAxis ( "Mouse ScrollWheel" ) * Time.deltaTime * zoomRate * Mathf.Abs ( desiredDistance );
desiredDistance = Mathf.Clamp ( desiredDistance, zoomMindistance, zoomMaxdistance );
correctedDistance = desiredDistance;
// Calculate desired camera position from `mouse wheel`
vTargetOffset = new Vector3 ( 0, -targetHeight, 0 );
}
private void Awake ( ) {
cam = GetComponent <Camera> ( );
}
private 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 ( GetComponent <Rigidbody> ( ) ) {
GetComponent <Rigidbody> ( ).freezeRotation = true;
}
startRotationX = 0.0f;
startRotationY = 0.0f;
}
private void Update ( ) {
if ( Input.GetMouseButton ( 0 ) ) {
xDeg += Input.GetAxis("Mouse Y") * sensitivityX * ( invertXRotation ? -1 : 1 );
yDeg += Input.GetAxis("Mouse X") * sensitivityY * ( invertYRotation ? -1 : 1 );
// Clamp X-Angle to prevent `camera` `flipping`
xDeg = ClampAngle ( xDeg, xMinPitch, xMaxPitch );
}
if ( Input.GetMouseButtonUp ( 0 ) ) {
xDeg = startRotationX;
yDeg = startRotationY;
}
// Set camera rotation
// Quaternion rotation = Quaternion.Euler ( xDeg, yDeg, 0 );
Quaternion rotation = Quaternion.Slerp(
transform.rotation, Quaternion.Euler(xDeg, yDeg, 0),
damper * Time.deltaTime
);
// Calculate `Zoom` for `camera`
CalculateZoom ( );
if ( target != null ) {
Vector3 position = target.position - ( rotation * Vector3.forward * desiredDistance + vTargetOffset );
var oldPosition = position;
// 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 & calculate
// the corrected distance
bool isCorrected = false;
if ( Physics.Linecast ( trueTargetPosition, position, out collisionHit, collisionLayers.value ) ) {
// Calculate the distance from the original estimated
// position to the collision location,
// subtracting out a safety "offset" distance from the
// object we hit
// The offset will help keep the camera from being
// right on top of the surface we hit,
// which usually shows up as the
// surface geometry getting
// partially clipped by the camera's front
// clipping plane
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 standard limits
currentDistance = Mathf.Clamp ( currentDistance, zoomMindistance, zoomMaxdistance );
// Recalculate position based on the new currentDistance
position = target.position - ( rotation * Vector3.forward * currentDistance + vTargetOffset );
// Set the `position`'s transform to the `recalculated`
// `position`
transform.position = position;
// Set the `rotation`'s transform to the `recalculated`
// `rotation`
transform.rotation = rotation;
}
}
}
The line{s} I’m looking at are : 112, 113 & 119 - 144
Here are the videos of the camera rotating correctly as well as incorrectly :
The 1st video is correct rotation
The 2nd video is incorrect rotation
vrj9zi
fk18kr
Any help is GREATLY appreciated!
Thanks & have a great day!