- Home /
Question by
Magic-4e · Aug 28, 2018 at 10:23 AM ·
cameraclippingspherecast
How to zoom the camera when obstructed?
Hi I have made a working script to avoid camera clipping with the help of a sphere cast.
The problem is that it sometimes picks the wrong wall to lean against at certain angels.
Can anyone help me out?
Here is my code:
using UnityEngine;
using System.Collections;
using System;
public class Thir_Pers_CameraController : MonoBehaviour
{
// *Public*
//Object to follow
public Transform target;
//Clamp angles (Keep it betwean 0 and 180)
public float maxUp_dontPass180 = 0f;
public float maxDown_dontPassZero = 0f;
//Camera movement speed
public float cameraSpeed = 1f;
//Invertable axis
public bool invertX = false;
public bool invertY = false;
// *Private*
//Player input value variables
private float camXinput = 0.0f;
private float camYinput = 0.0f;
//My up/down angle translation variable
private float currentYaxis = 0;
//Short version of clamp angles
private float maxUp = 0;
private float maxDown = 0;
//Number versions of invertor axis
private int invertorX = 1;
private int invertorY = 1;
//Camera
//public Camera playerCamera;
//Camera pivot points
GameObject CameraPivotY;
GameObject CameraPivotX;
GameObject PlayerGravityPivot;
//Objects with Ground tag
//GameObject[] groundObjects;
//Colliders of Ground
//Collider[] groundColliders;
//Camera frustum
//Plane[] cameraFrustum;
//Test frustum
//public float frustumCollide;
//Test far clip plane
//public float farClipPlane;
//Object that sphere cast hit's
public GameObject sphereHitObject;
//SphereCast radius
public float sphereRadius;
//SphereCast Max Distance
public float sphereMaxDistance;
//What has effect on sphereCast
public LayerMask sphereLayerMask;
//SphereCast origin
private Vector3 sphereOrigin;
//SphereCast direction
private Vector3 sphereDirection;
//Distance to object that has bean hit
public float sphereHitDistance;
void Start()
{
//Find cam X & Y pivots
CameraPivotY = GameObject.FindGameObjectWithTag("CameraPivotY");
CameraPivotX = GameObject.FindGameObjectWithTag("CameraPivotX");
//Find graf pivot
PlayerGravityPivot = GameObject.FindGameObjectWithTag("CameraGravityPivot");
//Turn long into short clamp varibles
maxUp = maxUp_dontPass180;
maxDown = maxDown_dontPassZero;
//Find camera Max distance
sphereMaxDistance = transform.position.z;
}
void FixedUpdate()
{
sphereOrigin = CameraPivotY.transform.position;
sphereDirection = -CameraPivotY.transform.forward;
RaycastHit[] hit;
hit = Physics.SphereCastAll(sphereOrigin, sphereRadius, sphereDirection, sphereMaxDistance, sphereLayerMask, QueryTriggerInteraction.UseGlobal);
if (hit.Length != 0)
{
sphereHitObject = hit[0].transform.gameObject;
sphereHitDistance = -hit[0].distance;
transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y, sphereHitDistance);
}
else
{
sphereHitObject = null;
sphereHitDistance = -sphereMaxDistance;
transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y, sphereHitDistance);
}
/*
//Find all Ground objects
groundObjects = GameObject.FindGameObjectsWithTag("Ground");
//Get colliders of Ground objects
groundColliders = new Collider[groundObjects.Length];
for(int i = 0; i < groundObjects.Length; i++)
{
groundColliders[i] = groundObjects[i].GetComponent<Collider>();
}
//Get playerCamera frustum
cameraFrustum = GeometryUtility.CalculateFrustumPlanes(playerCamera);
//Change far clip plane into camera distance to player object
cameraFrustum[5].distance = -Vector3.Dot(cameraFrustum[5].normal, transform.position);
//Read far clip plane
farClipPlane = cameraFrustum[5].distance;
//Check if there is Ground in frustum
for (int i = 0; i < groundColliders.Length; i++)
{
if (!GeometryUtility.TestPlanesAABB(cameraFrustum, groundColliders[i].bounds))
{
if(i == groundColliders.Length - 1)
{
frustumCollide = 0;
}
}
else
{
i = groundColliders.Length;
frustumCollide = 1;
}
}
*/
//My user preference camera invertor script
invertorX = (invertX) ? -1 : 1;
invertorY = (invertY) ? -1 : 1;
//Get cam control inputs
camXinput = Input.GetAxis("Mouse X") * invertorX * cameraSpeed;
camYinput = Input.GetAxis("Mouse Y") * invertorY * cameraSpeed;
//*Camera move left and right (for some reson up and right are inverted)
CameraPivotX.transform.Rotate(Vector3.up * camXinput, Space.Self);
//My currentYaxis varible wich reads the left/right angle of my camera and translate's it to a straight 0 to 180 (it doosn't have a full 360 degrees but 2 halfs of the same value)
if(CameraPivotY.transform.localEulerAngles.x >= 0 && CameraPivotY.transform.localEulerAngles.x <= 90) //Test if camera angle is in the second quarter (wich reads too low)
{
currentYaxis = CameraPivotY.transform.localEulerAngles.x + 90; //Set the angle higher
}
if(CameraPivotY.transform.localEulerAngles.x >= 270 && CameraPivotY.transform.localEulerAngles.x <= 360) //Test if camera angle is in the first quarter (wich reads too high)
{
currentYaxis = CameraPivotY.transform.localEulerAngles.x - 270; //Set the angle lower
}
//*Camera move up and down combined with a clamping script wich uses my currentYaxis varible to determine where to clamp (it can't use a clamp value higher than 180 or below 0 becouse of my variable issues mentioned earlier)
if (camYinput < 0) //Check if player moves camera down
{
if (maxDown > (currentYaxis + camYinput)) //Test if player input causes camera angle to move past MaxDown
{
CameraPivotY.transform.Rotate(Vector3.right * (currentYaxis - maxDown) * -1, Space.Self); //Set camera angle to Max
}
else
{
CameraPivotY.transform.Rotate(Vector3.right * camYinput, Space.Self); //Move the camera
}
}
else if (camYinput > 0) //Check if player moves camera up
{
if (maxUp < (currentYaxis + camYinput)) //Test if player input causes camera angle to move past MaxUp
{
CameraPivotY.transform.Rotate(Vector3.right * (maxUp - currentYaxis), Space.Self); //Set camera angle to Max
}
else
{
CameraPivotY.transform.Rotate(Vector3.right * camYinput, Space.Self); //Move the camera
}
}
}
}
Comment