First of all I started off this tutorial : http://www.unitylabs.net/tutorials/gameplay-mechanics/third-person-camera-controller/5
Then I learned bit of raycasting and added simple collision - when an object is infront of the camera is moves forward.
Any ideas, questions or help improving the script are most welcome.
@script AddComponentMenu("Camera-Control/Camera Controller")
//#pragma strict forces static typing
var target : Transform;
private var distance : float = 5.0;
private var xSpeed = 250.0;
private var ySpeed = 120.0;
private var cameraMode = "third";
private var zoomMinLimit = 1;
private var zoomMaxLimit= 7;
private var tempDistance = -1.0;
private var x = 0.0;
private var y = 0.0;
private var autoFollow : boolean = false;
// raycast variables
var hit : RaycastHit;
var collider1 : Collider = new Collider();
function Start ()
{
var angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
}
function LateUpdate ()
{
if(Input.GetAxis("Camera Mode") > 0) {
cameraMode = "first";
distance = 0.0;
}
if(Input.GetAxis("Camera Mode") < 0) {
cameraMode = "third";
distance = 5.0;
}
if((Input.GetAxis("Camera Zoom") < 0) (cameraMode =="first")){
cameraMode = "third";
}
if(cameraMode == "third")
{
var characterRotation = target.transform.eulerAngles.y;
var cameraRotation = transform.eulerAngles.y;
if((Input.GetAxis("Camera Zoom") > 0) (distance > zoomMinLimit)){
//distance = distance -1 / (xSpeed * 0.02);
distance = distance - Input.GetAxis("Camera Zoom") / (xSpeed * 0.02);
}
if((Input.GetAxis("Camera Zoom") < 0) (distance < zoomMaxLimit)){
//distance = distance +1 / (xSpeed * 0.02);
distance = distance - Input.GetAxis("Camera Zoom") / (xSpeed * 0.02);
}
if(!autoFollow){
x += Input.GetAxis("Camera X") * xSpeed * 0.02;
y -= Input.GetAxis("Camera Y") * ySpeed * 0.02;
var rotation = Quaternion.Euler(y, x, 0);
var position;
if((tempDistance < 0) || (distance < tempDistance)){
position = rotation * Vector3(0.0, 1.4, -distance) + target.position;
} else {
position = rotation * Vector3(0.0, 1.4, -tempDistance) + target.position;
}
//the 1 should be changed to a part of characters height
transform.rotation = rotation;
transform.position = position;
} else {
x += Input.GetAxis("Camera X") * xSpeed * 0.02;
y -= Input.GetAxis("Camera Y") * ySpeed * 0.02;
if(Input.GetAxis("Vertical") || Input.GetAxis("Horizontal")){
rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(y, characterRotation, 0), Time.deltaTime * 3);
if((tempDistance < 0) || (distance < tempDistance)){
position = rotation * Vector3(0.0, 1.4, -distance) + target.position;
} else {
position = rotation * Vector3(0.0, 1.4, -tempDistance) + target.position;
}
x = characterRotation;
}
else{
rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(y, x, 0), Time.deltaTime * 3);
if((tempDistance < 0) || (distance < tempDistance)){
position = rotation * Vector3(0.0, 1.4, -distance) + target.position;
} else {
position = rotation * Vector3(0.0, 1.4, -tempDistance) + target.position;
}
}
transform.rotation = rotation;
transform.position = position;
}
}
else
{
characterRotation = target.transform.eulerAngles.y;
x = characterRotation;
rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, characterRotation, 0), Time.deltaTime * 3);
position = rotation * Vector3(0.0, 1.4, -distance) + target.position;
transform.rotation = rotation;
transform.position = position;
}
CameraRaycast();
}
function SwitchAutoFollow() {
autoFollow = !autoFollow;
if(autoFollow){
print("Auto Follow On");
} else {
print("Auto Follow Off");
}
}
function CameraRaycast(){
var fwd = transform.right;
var targetDir = target.transform.position - transform.position;
var forward = transform.forward;
var angle = Vector3.Angle(targetDir, forward);
var asd = Vector3(0,angle,0);
// This returns true if an object is hit by the ray
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward),hit, distance))
{
//stores the object hit
collider1 = hit.collider;
Debug.DrawLine(transform.position, hit.point, Color.red);
var colliderGo6o : Collider = hit.collider;
var distanceToCam = Vector3.Distance(colliderGo6o.ClosestPointOnBounds(transform.position),transform.position);
var distanceToChar = Vector3.Distance(colliderGo6o.ClosestPointOnBounds(transform.position),colliderGo6o.transform.position);
tempDistance = distance - (distanceToChar + distanceToCam);
//print("distance : " + distance +" hit distance : " + hit.distance + " tempDistance : " + tempDistance);
} else if(!Physics.Raycast(transform.position, transform.TransformDirection(-Vector3.forward), (distance - tempDistance))) {
tempDistance = -1;
}
}