/// <summary> /// Checks if there exists a wall in front of us as well as a flat surface to finish the climb on /// </summary> private bool CanGrabLedge(out Vector3 hitPosition, out GameObject grabbedObject) { hitPosition = Vector3.zero; grabbedObject = null; Vector3 o = controller.OffsetPosition(controller.head.Offset); Collider[] colliders = Physics.OverlapSphere(o, controller.radius + 0.2f, controller.Walkable); if (colliders.Length > 0) { foreach (var col in colliders) { SuperCollisionType type = col.GetComponent <SuperCollisionType>(); Vector3 closestPoint = SuperCollider.ClosestPointOnSurface(col, o, controller.radius); RaycastHit hit; col.Raycast(new Ray(o, closestPoint - o), out hit, Mathf.Infinity); if (Vector3.Angle(hit.normal, controller.up) < type.StandAngle) { continue; } if (Vector3.Angle(-hit.normal, lookDirection) < 60.0f) { Vector3 topOfHead = o + controller.up * controller.radius; Vector3 direction = Math3d.ProjectVectorOnPlane(controller.up, closestPoint - o); Vector3 rayOrigin = topOfHead + Math3d.AddVectorLength(direction, 0.02f); col.Raycast(new Ray(rayOrigin, controller.down), out hit, 0.5f); if (Vector3.Angle(hit.normal, controller.up) < 20.0f) { hitPosition = Math3d.ProjectPointOnPlane(controller.up, hit.point, topOfHead + direction); grabbedObject = col.gameObject; return(true); } } } } return(false); }