Hello,
I make a 3rd person game with a simple camera movement (child to the player, that’s it) but if I rotate the player near a wall the camera goes behind it and the player is not visible
I want the camera to move closer to the player if something like this has happened.
I have searched a lot to find a good script and I have found this —v The problem is that it has a lot of other functions too. What should I change so it has only the camera collision effect?
using UnityEngine;
using System.Collections;
public class WowCamera : MonoBehaviour
{
public Transform target;
public float targetHeight = 1.7f;
public float distance = 5.0f;
public float maxDistance = 20;
public float minDistance = .6f;
public float xSpeed = 250.0f;
public float ySpeed = 120.0f;
public int yMinLimit = -80;
public int yMaxLimit = 80;
public int zoomRate = 40;
public float rotationDampening = 3.0f;
public float zoomDampening = 5.0f;
private float x = 0.0f;
private float y = 0.0f;
private float currentDistance;
private float desiredDistance;
private float correctedDistance;
void Start ()
{
Vector3 angles = transform.eulerAngles;
x = angles.x;
y = angles.y;
currentDistance = distance;
desiredDistance = distance;
correctedDistance = distance;
// Make the rigid body not change rotation
if (rigidbody)
rigidbody.freezeRotation = true;
}
/**
* Camera logic on LateUpdate to only update after all character movement logic has been handled.
*/
void LateUpdate ()
{
// Don't do anything if target is not defined
if (!target)
return;
//If either mouse buttons are down, let the mouse govern camera position
if (Input.GetMouseButton(0) || Input.GetMouseButton(1))
{
x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
}
// otherwise, ease behind the target if any of the directional keys are pressed
else if (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0)
{
float targetRotationAngle = target.eulerAngles.y;
float currentRotationAngle = transform.eulerAngles.y;
x = Mathf.LerpAngle(currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime);
}
y = ClampAngle(y, yMinLimit, yMaxLimit);
// set camera rotation
Quaternion rotation = Quaternion.Euler(y, x, 0);
// 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 position = target.position - (rotation * Vector3.forward * desiredDistance + new Vector3(0, -targetHeight, 0));
// 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))
{
position = collisionHit.point;
correctedDistance = Vector3.Distance(trueTargetPosition, position);
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;
// recalculate position based on the new currentDistance
position = target.position - (rotation * Vector3.forward * currentDistance + new Vector3(0, -targetHeight, 0));
transform.rotation = rotation;
transform.position = position;
}
private static float ClampAngle(float angle, float min, float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
}