- Home /
How to move the camera closer to the player while there is an object between them?
I'm trying to find a way to move the camera closer to the player while there is an object between the two, then move the camera back to the default distance from the player when the object is no longer in the way. I've translated the mouse orbit script to c#, and then adapted it to what I needed, so I'll post that here. My attempt at this camera effect that I'm trying is in there, DistanceAdjustment. If anyone could help me that would be great. Thanks. using UnityEngine; using System.Collections; [AddComponentMenu("Controls/CameraControls")] public class CameraControls : MonoBehaviour { public Transform player; public float distance = 1; public float xSpeed = 1; public float ySpeed = 1; public float yMin = -20; public float yMax = 80; private float x = 0.0f; private float y = 0.0f; void Start () { Vector3 angles = transform.eulerAngles; x = angles.x; y = angles.y; } void LateUpdate () { DistanceAdjustment(); if(player) { x += Input.GetAxis("Mouse X") * xSpeed * 0.02f; y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f; y = ClampAngle(y, yMin, yMax); Quaternion rotation = Quaternion.Euler(y,x,0); Vector3 position = rotation * (new Vector3(0.0f, 0.0f, -distance)) + player.position; transform.rotation = rotation; transform.position = position; } } void DistanceAdjustment () { RaycastHit rayHit; if(Physics.Raycast(transform.position, Vector3.forward, out rayHit, 15)) { if(rayHit.collider.tag == "Buildings") { distance -= rayHit.distance; } else { print("no hits"); } } } 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); } }
Answer by robertbu · Aug 03, 2014 at 03:21 PM
Here is a bit of addition to your code. Not sure this will be enough when you get among buildings. You may have to raycast multiple times to prevent clipping on some building, but anyway this gives you a start.
using UnityEngine;
using System.Collections;
[AddComponentMenu("Controls/CameraControls")]
public class CameraControls : MonoBehaviour {
public Transform player;
public float unobstructedDist = 8.0f;
public float distSpeed = 1.25f;
public float xSpeed = 90;
public float ySpeed = 90;
public float yMin = -20;
public float yMax = 80;
private float x = 0.0f;
private float y = 0.0f;
private float distance;
private float desiredDist;
void Start () {
distance = unobstructedDist;
desiredDist = unobstructedDist;
Vector3 angles = transform.eulerAngles;
x = angles.x;
y = angles.y;
}
void LateUpdate () {
DistanceAdjustment();
distance = Mathf.Lerp (distance, desiredDist, Time.deltaTime * distSpeed);
if(player) {
x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
y = ClampAngle(y, yMin, yMax);
Quaternion rotation = Quaternion.Euler(y,x,0);
Vector3 position = rotation * (new Vector3(0.0f, 0.0f, -distance)) + player.position;
transform.rotation = rotation;
transform.position = position;
}
}
void DistanceAdjustment () {
RaycastHit rayHit;
if(Physics.Raycast(transform.position, transform.forward, out rayHit, 15)) {
if(rayHit.collider.tag == "Buildings") {
desiredDist = unobstructedDist - rayHit.distance;
}
else {
desiredDist = unobstructedDist;
}
}
}
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);
}
}
I've added 'unobstructedDist' and 'desiredDist' and a bit of code that Lerps between current distance (distance) and desiredDist. Note your Raycast was using Vector3.forward and needed to use transform.forward.