public static bool IsVisible(ShapeVisibilityTracker tracker, bool ignoreLocalCamera) { return(tracker.gameObject.activeInHierarchy && IsVisibleUsingCameraFrustum(tracker, ignoreLocalCamera) && QSBPlayerManager.GetPlayersWithCameras(!ignoreLocalCamera) .Any(x => VisibilityOccluder.CanYouSee(tracker, x.Camera.mainCamera.transform.position))); }
/* * Recursively traverse all lights under `parent`. */ private float TraverseLights(Transform parent) { float lightsum = 0.0f; LightSprite lightSprite = parent.gameObject.GetComponent <LightSprite>(); // if parent is not active, ignore if (!parent.gameObject.activeSelf) { return(lightsum); } // if parent is not a light, traverse its children and return immediately if (lightSprite == null) { foreach (Transform child in parent) { lightsum += TraverseLights(child); } return(lightsum); } // parent is a light. // calculate illumination from light Vector4 color = lightSprite.Color; float luminance = 0.3f * color.x + 0.59f * color.y + 0.11f * color.z; // red, green, blue components luminance *= color.w; // alpha component float dx = parent.position.x - transform.position.x; float dy = parent.position.y - transform.position.y; float distance = Mathf.Sqrt(dx * dx + dy * dy); float falloff_denom = Mathf.Pow(distance, visibility_illumination_falloff); // raycast to see if player is occluded CircleCollider2D player_collider = GetComponent <CircleCollider2D>(); Vector2 dir = transform.position - parent.position; float player_radius = player_collider.radius; float radius_offset = player_radius + 0.01f; // offset player radius //RaycastHit2D hit = Physics2D.Raycast(parent.position, dir, distance - (radius_offset)); RaycastHit2D[] hits = Physics2D.RaycastAll(parent.position, dir, distance - (radius_offset)); if (hits.Length == 0) { lightsum += luminance / falloff_denom; // inverse square fall-off } else { bool hit_visibility_occluder = false; foreach (RaycastHit2D hit in hits) { VisibilityOccluder visibility_occluder = hit.collider.gameObject.GetComponent <VisibilityOccluder>(); hit_visibility_occluder = visibility_occluder != null; if (hit_visibility_occluder) { float occlusion_multiplier = 1.0f - visibility_occluder.obstacle_multiplicative_alpha; lightsum += (luminance / falloff_denom) * occlusion_multiplier; break; } } if (!hit_visibility_occluder) { lightsum += luminance / falloff_denom; } } // TODO illumination from guard flashlights. Take flashlight cone shape into account. return(lightsum); }