using UnityEngine; using Academy.HoloToolkit.Unity; /// /// Determines when the occluded version of the planet should be visible. /// This script allows us to do selective occlusion, so the occlusionObject /// will only be rendered when a Spatial Mapping surface is occluding the planet, /// not when another hologram is responsible for the occlusion. /// public class PlanetOcclusion : MonoBehaviour { [Tooltip("Object to display when the planet is occluded.")] public GameObject occlusionObject; /// /// Points to raycast to when checking for occlusion. /// private Vector3[] checkPoints; // Use this for initialization void Start() { occlusionObject.SetActive(false); // Set the check points to use when testing for occlusion. MeshFilter filter = gameObject.GetComponent(); Vector3 extents = filter.mesh.bounds.extents; Vector3 center = filter.mesh.bounds.center; Vector3 top = new Vector3(center.x, center.y + extents.y, center.z); Vector3 left = new Vector3(center.x - extents.x, center.y, center.z); Vector3 right = new Vector3(center.x + extents.x, center.y, center.z); Vector3 bottom = new Vector3(center.x, center.y - extents.y, center.z); checkPoints = new Vector3[] { center, top, left, right, bottom }; } // Update is called once per frame void Update() { /* TODO: 5.a DEVELOPER CODING EXERCISE 5.a */ // Check to see if any of the planet's boundary points are occluded. for (int i = 0; i < checkPoints.Length; i++) { // 5.a: Convert the current checkPoint to world coordinates. // Call gameObject.transform.TransformPoint(checkPoints[i]). // Assign the result to a new Vector3 variable called 'checkPt'. Vector3 checkPt = gameObject.transform.TransformPoint(checkPoints[i]); // 5.a: Call Vector3.Distance() to calculate the distance // between the Main Camera's position and 'checkPt'. // Assign the result to a new float variable called 'distance'. float distance = Vector3.Distance(Camera.main.transform.position, checkPt); // 5.a: Take 'checkPt' and subtract the Main Camera's position from it. // Assign the result to a new Vector3 variable called 'direction'. Vector3 direction = checkPt - Camera.main.transform.position; // Used to indicate if the call to Physics.Raycast() was successful. bool raycastHit = false; // 5.a: Check if the planet is occluded by a spatial mapping surface. // Call Physics.Raycast() with the following arguments: // - Pass in the Main Camera's position as the origin. // - Pass in 'direction' for the direction. // - Pass in 'distance' for the maxDistance. // - Pass in SpatialMappingManager.Instance.LayerMask as layerMask. // Assign the result to 'raycastHit'. raycastHit = Physics.Raycast(Camera.main.transform.position, direction, distance, SpatialMappingManager.Instance.LayerMask); if (raycastHit) { // 5.a: Our raycast hit a surface, so the planet is occluded. // Set the occlusionObject to active. occlusionObject.SetActive(true); // At least one point is occluded, so break from the loop. break; } else { // 5.a: The Raycast did not hit, so the planet is not occluded. // Deactivate the occlusionObject. occlusionObject.SetActive(false); } } } }