Hi I'm trying to do a basic Camera Collision in unity, for convenience, here's the entire script (I actually got most of it from someone else who wrote the comments, if that's necessary to know):
/// /// /// CameraControllercs.cs /// Camera Controller in CSharp v2.1 /// using UnityEngine; using System.Collections; using UnityEngine.EventSystems; public class CameraController : MonoBehaviour { public GameObject target; // Target to follow public float targetHeight = 1.7f; // Vertical offset adjustment public float distance = 12.0f; // Default Distance public float offsetFromWall = 0.7f; // Bring camera away from any colliding objects public float maxDistance = 20f; // Maximum zoom Distance public float minDistance = 0.6f; // Minimum zoom Distance public float xSpeed = 200.0f; // Orbit speed (Left/Right) public float ySpeed = 200.0f; // Orbit speed (Up/Down) public float yMinLimit = -80f; // Looking up limit public float yMaxLimit = 80f; // Looking down limit public float zoomRate = 40f; // Zoom Speed public float rotationDampening = 3.0f; // Auto Rotation speed (higher = faster) public float zoomDampening = 5.0f; // Auto Zoom speed (Higher = faster) public int collisionLayers; // What the camera will collide with public bool lockToRearOfTarget = false; // Lock camera to rear of target public bool allowMouseInputX = true; // Allow player to control camera angle on the X axis (Left/Right) public bool allowMouseInputY = true; // Allow player to control camera angle on the Y axis (Up/Down) private float xDeg = 0.0f; private float yDeg = 0.0f; private float currentDistance; private float desiredDistance; private float correctedDistance; private bool rotateBehind = false; private bool mouseSideButton = false; private float pbuffer = 0.0f; //Cooldownpuffer for SideButtons private float coolDown = 0.5f; //Cooldowntime for SideButtons GameObject main; void Start() { collisionLayers = LayerMask.GetMask("Default"); var temp = GameObject.Find("main"); if(temp != null) { main = temp; } Vector3 angles = transform.eulerAngles; xDeg = angles.x; yDeg = angles.y; currentDistance = distance; desiredDistance = distance; correctedDistance = distance; Camera.main.nearClipPlane = 0.001f; if (lockToRearOfTarget) rotateBehind = true; } void Update() { if (target == null) { target = GameObject.FindGameObjectWithTag("Player") as GameObject; Debug.Log("Looking for Player"); } } //Only Move camera after everything else has been updated void FixedUpdate() { // Don't do anything if target is not defined if (target == null) return; //pushbuffer if (pbuffer > 0) pbuffer -= Time.deltaTime; if (pbuffer currentDistance ? Mathf.Lerp(currentDistance, correctedDistance, Time.deltaTime * zoomDampening) : Mathf.Lerp(currentDistance, correctedDistance, Time.deltaTime * zoomDampening * 3); // Keep within limits currentDistance = Mathf.Clamp(currentDistance, minDistance, maxDistance); // Recalculate position based on the new currentDistance position = target.transform.position - (rotation * Vector3.forward * currentDistance + vTargetOffset); //Finally Set rotation and position of camera transform.rotation = rotation; transform.position = position; } private void RotateBehindTarget() { float targetRotationAngle = target.transform.eulerAngles.y; float currentRotationAngle = transform.eulerAngles.y; xDeg = Mathf.LerpAngle(currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime); // Stop rotating behind if not completed if (targetRotationAngle == currentRotationAngle) { if (!lockToRearOfTarget) rotateBehind = false; } else rotateBehind = true; } private float ClampAngle(float angle, float min, float max) { if (angle 360f) angle -= 360f; return Mathf.Clamp(angle, min, max); } }
As you can see in the start function, I also set the near clipping to a low value (the camera has a MainCamera tag BTW).
The problem: as you can see in this picture
even with the low nearClipping value, and the high offsetFromWall value (0.7f when it's normally 0.1f), the camera is still clipping the ground when moving it with the mouse semi-fast (when it's moved kind of slow it's not a problem).
I have no idea how to fix this, if I make the nearClipping lower the whole render gets messed up, and even then it doesn't work, so what else can I do to ensure that the user never sees underneath the ground?