//need to fix public bool IfObjectInFieldOfView(Ibounds ib, bool useBoundsCheck = false) { if ((ib.Transform.position - eye.position).sqrMagnitude > viewDistance * viewDistance) { return(false); } if (useBoundsCheck) { //1. Simple check if the center of object inside Field of View if (Vector3.Angle(eye.forward, ib.Transform.position - eye.position) < viewAngle / 2) { return(true); //and then return. } //2. Advanced bounds checking Vector3[] vertices = ib.Vertices; float boundsHeight_1 = vertices[0].y - 0.1f; //get bounds height Vector3 orginalPos_fixed = new Vector3(eye.position.x, boundsHeight_1, eye.position.z); Vector3 forwardPos = eye.forward * viewDistance + eye.position; Vector3 forwardPos_Fixed = new Vector3(forwardPos.x, boundsHeight_1, forwardPos.z) - orginalPos_fixed; // check if we can directly get raycast from forward direction if (Physics.Raycast(orginalPos_fixed, forwardPos_Fixed, viewDistance)) { return(true); } else { //check if any vertices of the bounds inside view angle. if there is, we raycast the tow view edge //if hit the collider. means we can see the bounds foreach (Vector3 v in vertices) { //Check if corner inside the view angle if (Vector3.Angle(forwardPos_Fixed, v - orginalPos_fixed) < viewAngle / 2.0f) { if (ScanFromViewEdge(orginalPos_fixed, forwardPos_Fixed, 5)) { return(true); } } } } return(false); } //Use simple object cnenter forward angle checking else if (Vector3.Angle(eye.forward, ib.Transform.position - eye.position) < viewAngle / 2) { return(true); } return(false); }
public void GetAllColliderInsideFieldOfView <T>(ref List <T> allColliderTInView, Action callBack, bool boundsRaycast = false) where T : MonoBehaviour { //get all Collider in a sphere Collider[] allColliders = Physics.OverlapSphere(eye.position, viewDistance); //get all Collider in View foreach (Collider c in allColliders) { T t = c.GetComponent <T>(); if (t) { //1. if the t aready in side the List, we skipe if (allColliderTInView.Contains(t)) { continue; } //Debug.Log(Vector3.Angle(eye.forward, c.transform.position - eye.position)); if (boundsRaycast) { //2. Simple check if the center of object inside Field of View if (Vector3.Angle(eye.forward, c.transform.position - eye.position) < viewAngle / 2) { allColliderTInView.Add(t); callBack(); continue; //and then return. } Ibounds b = c.GetComponent <Ibounds>(); Vector3[] vertices = b.Vertices; float boundsHeight_1 = b.Bounds.center.y; //get bounds height //instead of use a magic number. we should use bounds.center.y Vector3 orginalPos_fixed = new Vector3(eye.position.x, boundsHeight_1, eye.position.z); Vector3 forwardUnnormaledDir = eye.forward * viewDistance + eye.position; Vector3 forwardUnnormaledDir_Fixed = new Vector3(forwardUnnormaledDir.x, boundsHeight_1, forwardUnnormaledDir.z) - orginalPos_fixed; RaycastHit hitinfo; //3. Raycast forward. // check if we can directly get raycast from forward direction. //for some very big object, for player to the center angle check may not work. if (Physics.Raycast(orginalPos_fixed, forwardUnnormaledDir_Fixed, out hitinfo, viewDistance)) { if (hitinfo.collider.gameObject == c.gameObject) { allColliderTInView.Add(t); callBack(); continue; } } else //4.Scan Field Of View { //check if any vertices of the bounds inside view angle. if there is, we raycast the tow view edge //if hit the collider. means we can see the bounds foreach (Vector3 v in vertices) { //Check if corner inside the view angle if (Vector3.Angle(forwardUnnormaledDir_Fixed, v - orginalPos_fixed) < viewAngle / 2.0f) { if (ScanFromViewEdge(orginalPos_fixed, forwardUnnormaledDir_Fixed, 5)) { allColliderTInView.Add(t); callBack(); break; } } } } } //Dont use bounds raycast else if (Vector3.Angle(eye.forward, c.transform.position - eye.position) < viewAngle / 2) { allColliderTInView.Add(t); callBack(); } } } }