public static bool ComputeCameraMinorMajorAngle(Camera cam, ComputeCameraMinorMajorAngleOptions options, out SectionAngle angles) { const float raycastDistance = 512f; if (!cam) { angles = SectionAngle.Null; return(false); } Transform camTransform = cam.transform; Vector3 camPosition = camTransform.position; Vector3[] frustumCorners = new Vector3[4]; cam.CalculateFrustumCorners(new Rect(0, 0, 1, 1), cam.farClipPlane, Camera.MonoOrStereoscopicEye.Mono, frustumCorners); Vector3[] frustumCornersHit = new Vector3[4]; float[] minorAngles = new float[4]; float[] majorAngles = new float[4]; RaycastHit hit; for (int i = 0; i < frustumCorners.Length; ++i) { var worldSpaceCorner = camTransform.TransformPoint(frustumCorners[i]); Ray ray = new Ray(camPosition, (worldSpaceCorner - camPosition).normalized); if (!Physics.Raycast(ray, out hit, raycastDistance, options.landLayerMask)) { GameMain.ErrorTracking.Add("Fail to raycast mountain. See red ray from camera."); Debug.DrawLine(ray.origin, ray.origin + ray.direction * raycastDistance, Color.red); angles = SectionAngle.Null; return(false); } frustumCornersHit[i] = hit.point; Debug.DrawLine(camPosition, frustumCornersHit[i], Color.magenta); Torus.GetAngle(frustumCornersHit[i], out majorAngles[i], out minorAngles[i]); } var frustumCornersCenterHit = (frustumCornersHit[0] + frustumCornersHit[1] + frustumCornersHit[2] + frustumCornersHit[3]) * .25f; Debug.DrawLine(camPosition, frustumCornersCenterHit, Color.cyan); angles = SectionAngle.Null; return(false); // 0 => bottom-left // 1 => top-left // 2 => top-right // 3 => bottom-right float majorStart; float majorEnd; float minorStart; float minorEnd; Tools.GetStartEndAngle(majorAngles[1], majorAngles[2], out majorStart, out majorEnd); Tools.GetStartEndAngle(minorAngles[0], minorAngles[1], out minorStart, out minorEnd); Debug.Log($"minorStart:{minorStart} minorEnd:{minorEnd} majorStart:{majorStart} majorEnd:{majorEnd}"); majorStart -= options.majorPadding; majorEnd += options.majorPadding; minorStart -= options.minorPadding; minorEnd += options.minorPadding; angles.majorStart = Tools.Snap(majorStart, options.majorIncrement) % 360f; angles.majorEnd = Tools.Snap(majorEnd, options.majorIncrement) % 360f; angles.minorStart = Tools.Snap(minorStart, options.minorIncrement) % 360f; angles.minorEnd = Tools.Snap(minorEnd, options.minorIncrement) % 360f; angles.minorLength = (angles.minorEnd - angles.minorStart) % 360f; angles.majorLength = (angles.majorEnd - angles.majorStart) % 360f; return(true); }