using System.Collections; using UnityEngine; namespace NanoBrain.Braitenberg { //[RequireComponent(typeof(Collider))] // optional public class LightSensor : Sensor { [Tooltip("If true, perform occlusion checks with raycasts.")] public bool useOcclusion = true; [Tooltip("Angle (degrees) for directional sensitivity; 180 = omnidirectional.")] public float sensitivityAngle = 180f; [Tooltip("Multiplier to scale final output.")] public float multiplier = 1f; protected override float SampleSensor() { float sum = 0f; // Get all active lights in scene (Point lights only) Light[] lights = FindObjectsByType(); Vector3 pos = transform.position; Vector3 forward = transform.forward; float halfAngleCos = Mathf.Cos(sensitivityAngle * 0.5f * Mathf.Deg2Rad); int lightCount = 0; foreach (Light light in lights) { if (!light.enabled || light.type != LightType.Point) continue; // quick distance check float dist = Vector3.Distance(light.transform.position, pos); if (dist > this.sensorRange + light.range) continue; // outside both sensor and light ranges // angular sensitivity Vector3 toLight = (light.transform.position - pos).normalized; if (sensitivityAngle < 180f) { if (Vector3.Dot(forward, toLight) < halfAngleCos) continue; } // compute light falloff: Unity point lights use inverse squared (physically plausible) // you can approximate using L.intensity and L.range float attenuation = 0f; if (dist < light.range) { // inverse-square like falloff (avoid divide-by-zero) attenuation = light.intensity / Mathf.Max(0.01f, dist * dist); // optionally scale by (1 - dist/range) for a linear blend: attenuation *= 1f - dist / light.range; } else continue; // occlusion check if (useOcclusion) { Vector3 dir = (light.transform.position - pos).normalized; float rayDist = Mathf.Min(dist, light.range); if (Physics.Raycast(pos, dir, out RaycastHit hit, rayDist, senseLayer)) attenuation *= 0f; // completely blocked; or reduce by factor } //Debug.DrawRay(this.transform.position, toLight * sensorRange); // color consideration: convert light color to luminance if needed float luminance = RGBToLuminance(light.color) * attenuation; //Debug.Log(luminance); sum += luminance; lightCount++; } return (sum / lightCount) * multiplier; } static float RGBToLuminance(Color c) { // simple Rec.709 luminance return 0.2126f * c.r + 0.7152f * c.g + 0.0722f * c.b; } } }