- Home /
Camera Movement issue
hey guys. i have a camera movement c# script that follows the player and also has mouse orbit. however, the camera goes through the terrain and buildings and i want to fix that. here's the script:
using UnityEngine;
using System.Collections;
public class CameraMovement : MonoBehaviour { public Transform target; public float walkDistance; public float runDistance; public float height; public float xSpeed = 250.0f; public float ySpeed = 120.0f; public float heightDamping = 2.0f; public float rotationDamping = 3.0f;
private Transform _myTransform;
private float _x;
private float _y;
private bool _camButtonDown = false;
void Awake() {
_myTransform = transform;
}
// Use this for initialization
void Start () {
if(target == null)
Debug.LogWarning("there is no target assigned to the camera");
else {
CameraSetUp();
}
}
void Update() {
if(Input.GetMouseButtonDown(1)) { //Use the Input Manager to make this user selectable button
_camButtonDown = true;
}
if(Input.GetMouseButtonUp(1)) {
_camButtonDown = false;
}
}
void LateUpdate() {
// _myTransform.position = new Vector3(target.position.x, target.position.y + height, target.position.z - walkDistance); // _myTransform.LookAt(target);
if(target != null) { if(_camButtonDown) {
_x += Input.GetAxis("Mouse X") xSpeed 0.02f; _y -= Input.GetAxis("Mouse Y") ySpeed 0.02f;
// y = ClampAngle(y, yMinLimit, yMaxLimit);
Quaternion rotation = Quaternion.Euler(_y, _x, 0);
Vector3 position = rotation * new Vector3(0.0f, 0.0f, -walkDistance) + target.position;
_myTransform.rotation = rotation;
_myTransform.position = position;
}
else {
// _myTransform.position = new Vector3(target.position.x, target.position.y + height, target.position.z - walkDistance); // _myTransform.LookAt(target); _x = 0; _y = 0;
// Calculate the current rotation angles
float wantedRotationAngle = target.eulerAngles.y;
float wantedHeight = target.position.y + height;
float currentRotationAngle = _myTransform.eulerAngles.y;
float currentHeight = _myTransform.position.y;
// Damp the rotation around the y-axis
currentRotationAngle = Mathf.LerpAngle(currentRotationAngle, wantedRotationAngle, rotationDamping * Time.deltaTime);
// Damp the height
currentHeight = Mathf.Lerp(currentHeight, wantedHeight, heightDamping * Time.deltaTime);
// Convert the angle into a rotation
Quaternion currentRotation = Quaternion.Euler(0, currentRotationAngle, 0);
// Set the position of the camera on the x-z plane to:
// distance meters behind the target
_myTransform.position = target.position;
_myTransform.position -= currentRotation * Vector3.forward * walkDistance;
// Set the height of the camera
_myTransform.position = new Vector3(_myTransform.position.x, currentHeight, _myTransform.position.z);
// Always look at the target
_myTransform.LookAt (target);
}
}
}
public void CameraSetUp() {
_myTransform.position = new Vector3(target.position.x, target.position.y + height, target.position.z - walkDistance);
_myTransform.LookAt(target);
}
}
i know its a long script, but maybe someone can give some code in c# that keeps the camera from going through the terrain. thanks.
Answer by whydoidoit · Jun 20, 2012 at 11:24 AM
Your basic task is to position the camera above the terrain at the point it is located. You can get the terrain height from the terrain object. To stop it intersecting buildings you need to ray cast from the camera and see if it hits something before your character - then if it does you either zoom in or move the camera in some other way. Check out the orbitcamera script on my blog.
I might add, it's a worthwhile technique to add an empty game object called
PutativeCameraPosition
and attach to that a behaviour rather as you currently describe.
Then, make another empty game object called
LessPutativeCamerPosition
Or perhaps PutativeButImprovedBy$$anonymous$$ikesCodeCameraPosition
attach to that a behaviour which essentially does all that $$anonymous$$ike generously tells you here and in his popular blog.
Finally have an empty game object called CameraTripod which "merely" follows PutativeButImprovedBy$$anonymous$$ikesCodeCamerPosition (BUT if this is anything other than a hello world test, you'll ultimately have a whole lot of bollocks in there regarding smoothing network sawtoothing blah blah)
finally just attached your camera rig under that final object.
I encourage people to generally separate out "marker" objects like this.
Also generally to take a behaviour-ish approach to video games.
(Write in a behaviourish manner just to be cool - there's no other reason really. If you're as smart as $$anonymous$$r Data from Start Trek TNG, you can just write perfect spaghetti code, even over time domain, and everything will work perfectly. If you can do that, do it and get paid and go home to supper with the kids. This is where the catchphrase "$$anonymous$$r Data just writes spaghetti code" comes from. $$anonymous$$e, I'm so dense I adhere to the "no function over two lines long" comp sci dictum.)
i went on mike's blog and found the orbit camera script, but its saying it cant find the url. is there another way besides these that will work?
$$anonymous$$y old file host was a pig - the download should work now...
i tried it out in unity, but the camera just floated up from the ground. is there a way i could add some code to my camera movement script?
Your answer
Follow this Question
Related Questions
Ray camera to Terrain goes Wrong. 1 Answer
Erratic movement problem 2 Answers
Mouse Orbit + Move Object + Follow Problem 1 Answer
Moving replacing center object with orbiting object 0 Answers
Camera orbit around clicked position 0 Answers