Hey Guys,
I’m currently making a Action/adventure game similar to Zelda/Dark Souls and I was just wondering how I could re-orient my camera, so that when I’m locked onto them, the camera transitions above them so that you can see what exactly the character is now locked onto.
Here’s a snippet of my camera script modified from a WOWcamera.cs script.
using UnityEngine;
using System.Collections;
public class cameraCode : MonoBehaviour
{
public Transform target;
public static cameraCode Instance;
public float targetHeight = 1.7f;
public float distance = 5.0f;
public float offsetFromWall = 0.1f;
public float maxDistance = 20;
public float minDistance = .6f;
public float xSpeed = 200.0f;
public float ySpeed = 200.0f;
public int yMinLimit = -80;
public int yMaxLimit = 80;
public int zoomRate = 40;
public float rotationDampening = 3.0f;
public float zoomDampening = 5.0f;
public LayerMask collisionLayers = -1;
private float xDeg = 0.0f;
private float yDeg = 0.0f;
private float currentDistance;
private float desiredDistance;
private float correctedDistance;
void Start ()
{
Instance = this;
Vector3 angles = transform.eulerAngles;
xDeg = angles.x;
yDeg = 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 ()
{
Vector3 vtargetOffset;
// Don't do anything if target is not defined
if (!target)
return;
// If either mouse buttons are down, let the mouse govern camera position
xDeg += Input.GetAxis ("Mouse X") * xSpeed * 0.02f;
yDeg -= Input.GetAxis ("Mouse Y") * ySpeed * 0.02f;
//otherwise, ease behind the target if any of the directional keys are pressed
yDeg = ClampAngle (yDeg, yMinLimit, yMaxLimit);
// set camera rotation
Quaternion rotation = Quaternion.Euler (yDeg, xDeg, 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
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.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 legal limits
currentDistance = Mathf.Clamp (currentDistance, minDistance, maxDistance);
// recalculate position based on the new currentDistance
position = target.position - (rotation * Vector3.forward * currentDistance + vtargetOffset);
transform.rotation = rotation;
transform.position = position;
}
public void TargetLock()
{
float targetRotationAngle = target.eulerAngles.y;
float currentRotationAngle = transform.eulerAngles.y;
xDeg = Mathf.LerpAngle (currentRotationAngle, targetRotationAngle, rotationDampening * Time.fixedDeltaTime);
}
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);
}
}